remove unused includes
[blender-staging.git] / source / blender / editors / mesh / editmesh.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL 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.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * Contributor(s): Blender Foundation, full recode 2002-2008
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28
29 #include <stdlib.h>
30 #include <string.h>
31 #include <math.h>
32
33 #include "MEM_guardedalloc.h"
34
35
36 #include "DNA_key_types.h"
37
38 #include "BLI_blenlib.h"
39 #include "BLI_math.h"
40 #include "BLI_editVert.h"
41 #include "BLI_dynstr.h"
42 #include "BLI_rand.h"
43
44 #include "BKE_cloth.h"
45 #include "BKE_context.h"
46 #include "BKE_depsgraph.h"
47 #include "BKE_global.h"
48 #include "BKE_key.h"
49 #include "BKE_main.h"
50 #include "BKE_material.h"
51 #include "BKE_mesh.h"
52 #include "BKE_paint.h"
53
54 #include "ED_mesh.h"
55 #include "ED_object.h"
56 #include "ED_retopo.h"
57 #include "ED_screen.h"
58 #include "ED_util.h"
59 #include "ED_view3d.h"
60
61 #include "RNA_access.h"
62 #include "RNA_define.h"
63
64 #include "WM_api.h"
65 #include "WM_types.h"
66
67 /* own include */
68 #include "mesh_intern.h"
69
70 /* 
71 editmesh.c:
72         - add/alloc/free data
73         - hashtables
74         - enter/exit editmode
75 */
76
77 /* XXX */
78 static void BIF_undo_push(const char *dummy) {}
79 static void error(const char *dummy) {}
80
81
82 /* ***************** HASH ********************* */
83
84
85 #define EDHASHSIZE              (512*512)
86 #define EDHASH(a, b)    (a % EDHASHSIZE)
87
88
89 /* ************ ADD / REMOVE / FIND ****************** */
90
91 static void *calloc_em(EditMesh *em, size_t size, size_t nr)
92 {
93         return calloc(size, nr);
94 }
95
96 /* used to bypass normal calloc with fast one */
97 static void *(*callocvert)(EditMesh *, size_t, size_t) = calloc_em;
98 static void *(*callocedge)(EditMesh *, size_t, size_t) = calloc_em;
99 static void *(*callocface)(EditMesh *, size_t, size_t) = calloc_em;
100
101 EditVert *addvertlist(EditMesh *em, float *vec, EditVert *example)
102 {
103         EditVert *eve;
104         static int hashnr= 0;
105
106         eve= callocvert(em, sizeof(EditVert), 1);
107         BLI_addtail(&em->verts, eve);
108         em->totvert++;
109         
110         if(vec) VECCOPY(eve->co, vec);
111
112         eve->hash= hashnr++;
113         if( hashnr>=EDHASHSIZE) hashnr= 0;
114
115         /* new verts get keyindex of -1 since they did not
116          * have a pre-editmode vertex order
117          */
118         eve->keyindex = -1;
119
120         if(example) {
121                 CustomData_em_copy_data(&em->vdata, &em->vdata, example->data, &eve->data);
122                 eve->bweight = example->bweight;
123         }
124         else {
125                 CustomData_em_set_default(&em->vdata, &eve->data);
126         }
127
128         return eve;
129 }
130
131 void free_editvert (EditMesh *em, EditVert *eve)
132 {
133
134         EM_remove_selection(em, eve, EDITVERT);
135         CustomData_em_free_block(&em->vdata, &eve->data);
136         if(eve->fast==0)
137                 free(eve);
138         
139         em->totvert--;
140 }
141
142
143 EditEdge *findedgelist(EditMesh *em, EditVert *v1, EditVert *v2)
144 {
145         EditVert *v3;
146         struct HashEdge *he;
147
148         /* swap ? */
149         if( v1 > v2) {
150                 v3= v2; 
151                 v2= v1; 
152                 v1= v3;
153         }
154         
155         if(em->hashedgetab==NULL)
156                 em->hashedgetab= MEM_callocN(EDHASHSIZE*sizeof(struct HashEdge), "hashedgetab");
157
158         he= em->hashedgetab + EDHASH(v1->hash, v2->hash);
159         
160         while(he) {
161                 
162                 if(he->eed && he->eed->v1==v1 && he->eed->v2==v2) return he->eed;
163                 
164                 he= he->next;
165         }
166         return 0;
167 }
168
169 static void insert_hashedge(EditMesh *em, EditEdge *eed)
170 {
171         /* assuming that eed is not in the list yet, and that a find has been done before */
172         
173         struct HashEdge *first, *he;
174
175         first= em->hashedgetab + EDHASH(eed->v1->hash, eed->v2->hash);
176
177         if( first->eed==0 ) {
178                 first->eed= eed;
179         }
180         else {
181                 he= &eed->hash; 
182                 he->eed= eed;
183                 he->next= first->next;
184                 first->next= he;
185         }
186 }
187
188 static void remove_hashedge(EditMesh *em, EditEdge *eed)
189 {
190         /* assuming eed is in the list */
191         
192         struct HashEdge *first, *he, *prev=NULL;
193
194         he=first= em->hashedgetab + EDHASH(eed->v1->hash, eed->v2->hash);
195
196         while(he) {
197                 if(he->eed == eed) {
198                         /* remove from list */
199                         if(he==first) {
200                                 if(first->next) {
201                                         he= first->next;
202                                         first->eed= he->eed;
203                                         first->next= he->next;
204                                 }
205                                 else he->eed= 0;
206                         }
207                         else {
208                                 prev->next= he->next;
209                         }
210                         return;
211                 }
212                 prev= he;
213                 he= he->next;
214         }
215 }
216
217 EditEdge *addedgelist(EditMesh *em, EditVert *v1, EditVert *v2, EditEdge *example)
218 {
219         EditVert *v3;
220         EditEdge *eed;
221         int swap= 0;
222         
223         if(v1==v2) return NULL;
224         if(v1==NULL || v2==NULL) return NULL;
225
226         /* swap ? */
227         if(v1>v2) {
228                 v3= v2; 
229                 v2= v1; 
230                 v1= v3;
231                 swap= 1;
232         }
233         
234         /* find in hashlist */
235         eed= findedgelist(em, v1, v2);
236
237         if(eed==NULL) {
238         
239                 eed= (EditEdge *)callocedge(em, sizeof(EditEdge), 1);
240                 eed->v1= v1;
241                 eed->v2= v2;
242                 BLI_addtail(&em->edges, eed);
243                 eed->dir= swap;
244                 insert_hashedge(em, eed);
245                 em->totedge++;
246                 
247                 /* copy edge data:
248                    rule is to do this with addedgelist call, before addfacelist */
249                 if(example) {
250                         eed->crease= example->crease;
251                         eed->bweight= example->bweight;
252                         eed->sharp = example->sharp;
253                         eed->seam = example->seam;
254                         eed->h |= (example->h & EM_FGON);
255                 }
256         }
257
258         return eed;
259 }
260
261 void remedge(EditMesh *em, EditEdge *eed)
262 {
263         BLI_remlink(&em->edges, eed);
264         remove_hashedge(em, eed);
265         
266         em->totedge--;
267 }
268
269 void free_editedge(EditMesh *em, EditEdge *eed)
270 {
271         EM_remove_selection(em, eed, EDITEDGE);
272         if(eed->fast==0){ 
273                 free(eed);
274         }
275 }
276
277 void free_editface(EditMesh *em, EditFace *efa)
278 {
279         EM_remove_selection(em, efa, EDITFACE);
280         
281         if (em->act_face==efa) {
282                 EM_set_actFace(em, em->faces.first == efa ? NULL : em->faces.first);
283         }
284                 
285         CustomData_em_free_block(&em->fdata, &efa->data);
286         if(efa->fast==0)
287                 free(efa);
288         
289         em->totface--;
290 }
291
292 void free_vertlist(EditMesh *em, ListBase *edve) 
293 {
294         EditVert *eve, *next;
295
296         if (!edve) return;
297
298         eve= edve->first;
299         while(eve) {
300                 next= eve->next;
301                 free_editvert(em, eve);
302                 eve= next;
303         }
304         edve->first= edve->last= NULL;
305         em->totvert= em->totvertsel= 0;
306 }
307
308 void free_edgelist(EditMesh *em, ListBase *lb)
309 {
310         EditEdge *eed, *next;
311         
312         eed= lb->first;
313         while(eed) {
314                 next= eed->next;
315                 free_editedge(em, eed);
316                 eed= next;
317         }
318         lb->first= lb->last= NULL;
319         em->totedge= em->totedgesel= 0;
320 }
321
322 void free_facelist(EditMesh *em, ListBase *lb)
323 {
324         EditFace *efa, *next;
325         
326         efa= lb->first;
327         while(efa) {
328                 next= efa->next;
329                 free_editface(em, efa);
330                 efa= next;
331         }
332         lb->first= lb->last= NULL;
333         em->totface= em->totfacesel= 0;
334 }
335
336 EditFace *addfacelist(EditMesh *em, EditVert *v1, EditVert *v2, EditVert *v3, EditVert *v4, EditFace *example, EditFace *exampleEdges)
337 {
338         EditFace *efa;
339         EditEdge *e1, *e2=0, *e3=0, *e4=0;
340
341         /* added sanity check... seems to happen for some tools, or for enter editmode for corrupted meshes */
342         if(v1==v4 || v2==v4 || v3==v4) v4= NULL;
343         
344         /* add face to list and do the edges */
345         if(exampleEdges) {
346                 e1= addedgelist(em, v1, v2, exampleEdges->e1);
347                 e2= addedgelist(em, v2, v3, exampleEdges->e2);
348                 if(v4) e3= addedgelist(em, v3, v4, exampleEdges->e3); 
349                 else e3= addedgelist(em, v3, v1, exampleEdges->e3);
350                 if(v4) e4= addedgelist(em, v4, v1, exampleEdges->e4);
351         }
352         else {
353                 e1= addedgelist(em, v1, v2, NULL);
354                 e2= addedgelist(em, v2, v3, NULL);
355                 if(v4) e3= addedgelist(em, v3, v4, NULL); 
356                 else e3= addedgelist(em, v3, v1, NULL);
357                 if(v4) e4= addedgelist(em, 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(em, 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->flag= example->flag;
377                 CustomData_em_copy_data(&em->fdata, &em->fdata, example->data, &efa->data);
378         }
379         else {
380                 efa->mat_nr= em->mat_nr;
381
382                 CustomData_em_set_default(&em->fdata, &efa->data);
383         }
384
385         BLI_addtail(&em->faces, efa);
386         em->totface++;
387         
388         if(efa->v4) {
389                 normal_quad_v3( efa->n,efa->v1->co, efa->v2->co, efa->v3->co, efa->v4->co);
390                 cent_quad_v3(efa->cent, efa->v1->co, efa->v2->co, efa->v3->co, efa->v4->co);
391         }
392         else {
393                 normal_tri_v3( efa->n,efa->v1->co, efa->v2->co, efa->v3->co);
394                 cent_tri_v3(efa->cent, efa->v1->co, efa->v2->co, efa->v3->co);
395         }
396
397         return efa;
398 }
399
400 /* ************************ end add/new/find ************  */
401
402 /* ************************ Edit{Vert,Edge,Face} utilss ***************************** */
403
404 /* some nice utility functions */
405
406 EditVert *editedge_getOtherVert(EditEdge *eed, EditVert *eve)
407 {
408         if (eve==eed->v1) {
409                 return eed->v2;
410         } else if (eve==eed->v2) {
411                 return eed->v1;
412         } else {
413                 return NULL;
414         }
415 }
416
417 EditVert *editedge_getSharedVert(EditEdge *eed, EditEdge *eed2) 
418 {
419         if (eed->v1==eed2->v1 || eed->v1==eed2->v2) {
420                 return eed->v1;
421         } else if (eed->v2==eed2->v1 || eed->v2==eed2->v2) {
422                 return eed->v2;
423         } else {
424                 return NULL;
425         }
426 }
427
428 int editedge_containsVert(EditEdge *eed, EditVert *eve) 
429 {
430         return (eed->v1==eve || eed->v2==eve);
431 }
432
433 int editface_containsVert(EditFace *efa, EditVert *eve) 
434 {
435         return (efa->v1==eve || efa->v2==eve || efa->v3==eve || (efa->v4 && efa->v4==eve));
436 }
437
438 int editface_containsEdge(EditFace *efa, EditEdge *eed) 
439 {
440         return (efa->e1==eed || efa->e2==eed || efa->e3==eed || (efa->e4 && efa->e4==eed));
441 }
442
443
444 /* ************************ stuct EditMesh manipulation ***************************** */
445
446 /* fake callocs for fastmalloc below */
447 static void *calloc_fastvert(EditMesh *em, size_t size, size_t nr)
448 {
449         EditVert *eve= em->curvert++;
450         eve->fast= 1;
451         return eve;
452 }
453 static void *calloc_fastedge(EditMesh *em, size_t size, size_t nr)
454 {
455         EditEdge *eed= em->curedge++;
456         eed->fast= 1;
457         return eed;
458 }
459 static void *calloc_fastface(EditMesh *em, size_t size, size_t nr)
460 {
461         EditFace *efa= em->curface++;
462         efa->fast= 1;
463         return efa;
464 }
465
466 /* allocate 1 chunk for all vertices, edges, faces. These get tagged to
467    prevent it from being freed
468 */
469 static void init_editmesh_fastmalloc(EditMesh *em, int totvert, int totedge, int totface)
470 {
471         if(totvert) em->allverts= MEM_callocN(totvert*sizeof(EditVert), "allverts");
472         else em->allverts= NULL;
473         em->curvert= em->allverts;
474         
475         if(totedge==0) totedge= 4*totface;      // max possible
476
477         if(totedge) em->alledges= MEM_callocN(totedge*sizeof(EditEdge), "alledges");
478         else em->alledges= NULL;
479         em->curedge= em->alledges;
480         
481         if(totface) em->allfaces= MEM_callocN(totface*sizeof(EditFace), "allfaces");
482         else em->allfaces= NULL;
483         em->curface= em->allfaces;
484
485         callocvert= calloc_fastvert;
486         callocedge= calloc_fastedge;
487         callocface= calloc_fastface;
488 }
489
490 static void end_editmesh_fastmalloc(void)
491 {
492         callocvert= calloc_em;
493         callocedge= calloc_em;
494         callocface= calloc_em;
495 }
496
497 /* do not free editmesh itself here */
498 void free_editMesh(EditMesh *em)
499 {
500         if(em==NULL) return;
501
502         if(em->verts.first) free_vertlist(em, &em->verts);
503         if(em->edges.first) free_edgelist(em, &em->edges);
504         if(em->faces.first) free_facelist(em, &em->faces);
505         if(em->selected.first) BLI_freelistN(&(em->selected));
506
507         CustomData_free(&em->vdata, 0);
508         CustomData_free(&em->fdata, 0);
509
510         if(em->derivedFinal) {
511                 if (em->derivedFinal!=em->derivedCage) {
512                         em->derivedFinal->needsFree= 1;
513                         em->derivedFinal->release(em->derivedFinal);
514                 }
515                 em->derivedFinal= NULL;
516         }
517         if(em->derivedCage) {
518                 em->derivedCage->needsFree= 1;
519                 em->derivedCage->release(em->derivedCage);
520                 em->derivedCage= NULL;
521         }
522
523         /* DEBUG: hashtabs are slowest part of enter/exit editmode. here a testprint */
524 #if 0
525         if(em->hashedgetab) {
526                 HashEdge *he, *hen;
527                 int a, used=0, max=0, nr;
528                 he= em->hashedgetab;
529                 for(a=0; a<EDHASHSIZE; a++, he++) {
530                         if(he->eed) used++;
531                         hen= he->next;
532                         nr= 0;
533                         while(hen) {
534                                 nr++;
535                                 hen= hen->next;
536                         }
537                         if(max<nr) max= nr;
538                 }
539                 printf("hastab used %d max %d\n", used, max);
540         }
541 #endif
542         if(em->hashedgetab) MEM_freeN(em->hashedgetab);
543         em->hashedgetab= NULL;
544         
545         if(em->allverts) MEM_freeN(em->allverts);
546         if(em->alledges) MEM_freeN(em->alledges);
547         if(em->allfaces) MEM_freeN(em->allfaces);
548         
549         em->allverts= em->curvert= NULL;
550         em->alledges= em->curedge= NULL;
551         em->allfaces= em->curface= NULL;
552         
553         mesh_octree_table(NULL, NULL, NULL, 'e');
554         mesh_mirrtopo_table(NULL, 'e');
555
556         em->totvert= em->totedge= em->totface= 0;
557
558 // XXX  if(em->retopo_paint_data) retopo_free_paint_data(em->retopo_paint_data);
559         em->retopo_paint_data= NULL;
560         em->act_face = NULL;
561 }
562
563 static void editMesh_set_hash(EditMesh *em)
564 {
565         EditEdge *eed;
566
567         if(em->hashedgetab) MEM_freeN(em->hashedgetab);
568         em->hashedgetab= NULL;
569         
570         for(eed=em->edges.first; eed; eed= eed->next)  {
571                 if( findedgelist(em, eed->v1, eed->v2)==NULL )
572                         insert_hashedge(em, eed);
573         }
574
575 }
576
577
578 /* ************************ IN & OUT EDITMODE ***************************** */
579
580
581 static void edge_normal_compare(EditEdge *eed, EditFace *efa1)
582 {
583         EditFace *efa2;
584         float cent1[3], cent2[3];
585         float inp;
586         
587         efa2 = eed->tmp.f;
588         if(efa1==efa2) return;
589         
590         inp= efa1->n[0]*efa2->n[0] + efa1->n[1]*efa2->n[1] + efa1->n[2]*efa2->n[2];
591         if(inp<0.999 && inp >-0.999) eed->f2= 1;
592                 
593         if(efa1->v4) cent_quad_v3(cent1, efa1->v1->co, efa1->v2->co, efa1->v3->co, efa1->v4->co);
594         else cent_tri_v3(cent1, efa1->v1->co, efa1->v2->co, efa1->v3->co);
595         if(efa2->v4) cent_quad_v3(cent2, efa2->v1->co, efa2->v2->co, efa2->v3->co, efa2->v4->co);
596         else cent_tri_v3(cent2, efa2->v1->co, efa2->v2->co, efa2->v3->co);
597         
598         sub_v3_v3v3(cent1, cent2, cent1);
599         normalize_v3(cent1);
600         inp= cent1[0]*efa1->n[0] + cent1[1]*efa1->n[1] + cent1[2]*efa1->n[2]; 
601
602         if(inp < -0.001 ) eed->f1= 1;
603 }
604
605 #if 0
606 typedef struct {
607         EditEdge *eed;
608         float noLen,no[3];
609         int adjCount;
610 } EdgeDrawFlagInfo;
611
612 static int edgeDrawFlagInfo_cmp(const void *av, const void *bv)
613 {
614         const EdgeDrawFlagInfo *a = av;
615         const EdgeDrawFlagInfo *b = bv;
616
617         if (a->noLen<b->noLen) return -1;
618         else if (a->noLen>b->noLen) return 1;
619         else return 0;
620 }
621 #endif
622
623 static void edge_drawflags(Mesh *me, EditMesh *em)
624 {
625         EditVert *eve;
626         EditEdge *eed, *e1, *e2, *e3, *e4;
627         EditFace *efa;
628         
629         /* - count number of times edges are used in faces: 0 en 1 time means draw edge
630          * - edges more than 1 time used: in *tmp.f is pointer to first face
631          * - check all faces, when normal differs to much: draw (flag becomes 1)
632          */
633
634         /* later on: added flags for 'cylinder' and 'sphere' intersection tests in old
635            game engine (2.04)
636          */
637         
638         recalc_editnormals(em);
639         
640         /* init */
641         eve= em->verts.first;
642         while(eve) {
643                 eve->f1= 1;             /* during test it's set at zero */
644                 eve= eve->next;
645         }
646         eed= em->edges.first;
647         while(eed) {
648                 eed->f2= eed->f1= 0;
649                 eed->tmp.f = 0;
650                 eed= eed->next;
651         }
652
653         efa= em->faces.first;
654         while(efa) {
655                 e1= efa->e1;
656                 e2= efa->e2;
657                 e3= efa->e3;
658                 e4= efa->e4;
659                 if(e1->f2<4) e1->f2+= 1;
660                 if(e2->f2<4) e2->f2+= 1;
661                 if(e3->f2<4) e3->f2+= 1;
662                 if(e4 && e4->f2<4) e4->f2+= 1;
663                 
664                 if(e1->tmp.f == 0) e1->tmp.f = (void *) efa;
665                 if(e2->tmp.f == 0) e2->tmp.f = (void *) efa;
666                 if(e3->tmp.f ==0) e3->tmp.f = (void *) efa;
667                 if(e4 && (e4->tmp.f == 0)) e4->tmp.f = (void *) efa;
668                 
669                 efa= efa->next;
670         }
671
672         if(me->drawflag & ME_ALLEDGES) {
673                 efa= em->faces.first;
674                 while(efa) {
675                         if(efa->e1->f2>=2) efa->e1->f2= 1;
676                         if(efa->e2->f2>=2) efa->e2->f2= 1;
677                         if(efa->e3->f2>=2) efa->e3->f2= 1;
678                         if(efa->e4 && efa->e4->f2>=2) efa->e4->f2= 1;
679                         
680                         efa= efa->next;
681                 }               
682         }       
683         else {
684                 
685                 /* handle single-edges for 'test cylinder flag' (old engine) */
686                 
687                 eed= em->edges.first;
688                 while(eed) {
689                         if(eed->f2==1) eed->f1= 1;
690                         eed= eed->next;
691                 }
692
693                 /* all faces, all edges with flag==2: compare normal */
694                 efa= em->faces.first;
695                 while(efa) {
696                         if(efa->e1->f2==2) edge_normal_compare(efa->e1, efa);
697                         else efa->e1->f2= 1;
698                         if(efa->e2->f2==2) edge_normal_compare(efa->e2, efa);
699                         else efa->e2->f2= 1;
700                         if(efa->e3->f2==2) edge_normal_compare(efa->e3, efa);
701                         else efa->e3->f2= 1;
702                         if(efa->e4) {
703                                 if(efa->e4->f2==2) edge_normal_compare(efa->e4, efa);
704                                 else efa->e4->f2= 1;
705                         }
706                         efa= efa->next;
707                 }
708                 
709                 /* sphere collision flag */
710                 
711                 eed= em->edges.first;
712                 while(eed) {
713                         if(eed->f1!=1) {
714                                 eed->v1->f1= eed->v2->f1= 0;
715                         }
716                         eed= eed->next;
717                 }
718                 
719         }
720 }
721
722 /* turns Mesh into editmesh */
723 void make_editMesh(Scene *scene, Object *ob)
724 {
725         Mesh *me= ob->data;
726         MFace *mface;
727         MVert *mvert;
728         MSelect *mselect;
729         KeyBlock *actkey;
730         EditMesh *em;
731         EditVert *eve, **evlist, *eve1, *eve2, *eve3, *eve4;
732         EditFace *efa, *efa_last_sel= NULL;
733         EditEdge *eed;
734         EditSelection *ese;
735         float *co, (*keyco)[3]= NULL;
736         int tot, a, eekadoodle= 0;
737
738         if(me->edit_mesh==NULL)
739                 me->edit_mesh= MEM_callocN(sizeof(EditMesh), "editmesh");
740         else 
741                 /* because of reload */
742                 free_editMesh(me->edit_mesh);
743         
744         em= me->edit_mesh;
745         
746         em->selectmode= scene->toolsettings->selectmode; // warning needs to be synced
747         em->act_face = NULL;
748         em->totvert= tot= me->totvert;
749         em->totedge= me->totedge;
750         em->totface= me->totface;
751         
752         if(tot==0) {
753                 return;
754         }
755         
756         if(ob->actcol > 0)
757                 em->mat_nr= ob->actcol-1;
758
759         /* initialize fastmalloc for editmesh */
760         init_editmesh_fastmalloc(em, me->totvert, me->totedge, me->totface);
761
762         actkey = ob_get_keyblock(ob);
763         if(actkey) {
764                 /* undo-ing in past for previous editmode sessions gives corrupt 'keyindex' values */
765                 undo_editmode_clear();
766                 keyco= actkey->data;
767                 em->shapenr= ob->shapenr;
768         }
769
770         /* make editverts */
771         CustomData_copy(&me->vdata, &em->vdata, CD_MASK_EDITMESH, CD_CALLOC, 0);
772         mvert= me->mvert;
773
774         evlist= (EditVert **)MEM_mallocN(tot*sizeof(void *),"evlist");
775         for(a=0; a<tot; a++, mvert++) {
776                 
777                 co= mvert->co;
778
779                 /* edit the shape key coordinate if available */
780                 if(keyco && a < actkey->totelem)
781                         co= keyco[a];
782
783                 eve= addvertlist(em, co, NULL);
784                 evlist[a]= eve;
785                 
786                 /* face select sets selection in next loop */
787                 if(!paint_facesel_test(ob))
788                         eve->f |= (mvert->flag & 1);
789                 
790                 if (mvert->flag & ME_HIDE) eve->h= 1;           
791                 eve->no[0]= mvert->no[0]/32767.0;
792                 eve->no[1]= mvert->no[1]/32767.0;
793                 eve->no[2]= mvert->no[2]/32767.0;
794
795                 eve->bweight= ((float)mvert->bweight)/255.0f;
796
797                 /* lets overwrite the keyindex of the editvert
798                  * with the order it used to be in before
799                  * editmode
800                  */
801                 eve->keyindex = a;
802
803                 CustomData_to_em_block(&me->vdata, &em->vdata, a, &eve->data);
804         }
805
806         if(actkey && actkey->totelem!=me->totvert);
807         else {
808                 MEdge *medge= me->medge;
809                 
810                 CustomData_copy(&me->edata, &em->edata, CD_MASK_EDITMESH, CD_CALLOC, 0);
811                 /* make edges */
812                 for(a=0; a<me->totedge; a++, medge++) {
813                         eed= addedgelist(em, evlist[medge->v1], evlist[medge->v2], NULL);
814                         /* eed can be zero when v1 and v2 are identical, dxf import does this... */
815                         if(eed) {
816                                 eed->crease= ((float)medge->crease)/255.0f;
817                                 eed->bweight= ((float)medge->bweight)/255.0f;
818                                 
819                                 if(medge->flag & ME_SEAM) eed->seam= 1;
820                                 if(medge->flag & ME_SHARP) eed->sharp = 1;
821                                 if(medge->flag & SELECT) eed->f |= SELECT;
822                                 if(medge->flag & ME_FGON) eed->h= EM_FGON;      // 2 different defines!
823                                 if(medge->flag & ME_HIDE) eed->h |= 1;
824                                 if(em->selectmode==SCE_SELECT_EDGE) 
825                                         EM_select_edge(eed, eed->f & SELECT);           // force edge selection to vertices, seems to be needed ...
826                                 CustomData_to_em_block(&me->edata,&em->edata, a, &eed->data);
827                         }
828                 }
829                 
830                 CustomData_copy(&me->fdata, &em->fdata, CD_MASK_EDITMESH, CD_CALLOC, 0);
831
832                 /* make faces */
833                 mface= me->mface;
834
835                 for(a=0; a<me->totface; a++, mface++) {
836                         eve1= evlist[mface->v1];
837                         eve2= evlist[mface->v2];
838                         if(!mface->v3) eekadoodle= 1;
839                         eve3= evlist[mface->v3];
840                         if(mface->v4) eve4= evlist[mface->v4]; else eve4= NULL;
841                         
842                         efa= addfacelist(em, eve1, eve2, eve3, eve4, NULL, NULL);
843
844                         if(efa) {
845                                 CustomData_to_em_block(&me->fdata, &em->fdata, a, &efa->data);
846
847                                 efa->mat_nr= mface->mat_nr;
848                                 efa->flag= mface->flag & ~ME_HIDE;
849                                 
850                                 /* select and hide face flag */
851                                 if(mface->flag & ME_HIDE) {
852                                         efa->h= 1;
853                                 } else {
854                                         if (a==me->act_face) {
855                                                 EM_set_actFace(em, efa);
856                                         }
857                                         
858                                         /* dont allow hidden and selected */
859                                         if(mface->flag & ME_FACE_SEL) {
860                                                 efa->f |= SELECT;
861                                                 
862                                                 if(paint_facesel_test(ob)) {
863                                                         EM_select_face(efa, 1); /* flush down */
864                                                 }
865
866                                                 efa_last_sel= efa;
867                                         }
868                                 }
869                         }
870                 }
871         }
872         
873         if(EM_get_actFace(em, 0)==NULL && efa_last_sel) {
874                 EM_set_actFace(em, efa_last_sel);
875         }
876
877         if(eekadoodle)
878                 error("This Mesh has old style edgecodes, please put it in the bugtracker!");
879         
880         MEM_freeN(evlist);
881
882         end_editmesh_fastmalloc();      // resets global function pointers
883         
884         if(me->mselect){
885                 //restore editselections
886                 EM_init_index_arrays(em, 1,1,1);
887                 mselect = me->mselect;
888                 
889                 for(a=0; a<me->totselect; a++, mselect++){
890                         /*check if recorded selection is still valid, if so copy into editmesh*/
891                         if( (mselect->type == EDITVERT && me->mvert[mselect->index].flag & SELECT) || (mselect->type == EDITEDGE && me->medge[mselect->index].flag & SELECT) || (mselect->type == EDITFACE && me->mface[mselect->index].flag & ME_FACE_SEL) ){
892                                 ese = MEM_callocN(sizeof(EditSelection), "Edit Selection");
893                                 ese->type = mselect->type;      
894                                 if(ese->type == EDITVERT) ese->data = EM_get_vert_for_index(mselect->index); else
895                                 if(ese->type == EDITEDGE) ese->data = EM_get_edge_for_index(mselect->index); else
896                                 if(ese->type == EDITFACE) ese->data = EM_get_face_for_index(mselect->index);
897                                 BLI_addtail(&(em->selected),ese);
898                         }
899                 }
900                 EM_free_index_arrays();
901         }
902         /* this creates coherent selections. also needed for older files */
903         EM_selectmode_set(em);
904         /* paranoia check to enforce hide rules */
905         EM_hide_reset(em);
906         /* sets helper flags which arent saved */
907         EM_fgon_flags(em);
908         
909         if (EM_get_actFace(em, 0)==NULL) {
910                 EM_set_actFace(em, em->faces.first ); /* will use the first face, this is so we alwats have an active face */
911         }
912 }
913
914 /* makes Mesh out of editmesh */
915 void load_editMesh(Scene *scene, Object *ob)
916 {
917         Mesh *me= ob->data;
918         MVert *mvert, *oldverts;
919         MEdge *medge;
920         MFace *mface;
921         MSelect *mselect;
922         EditMesh *em= me->edit_mesh;
923         EditVert *eve;
924         EditFace *efa, *efa_act;
925         EditEdge *eed;
926         EditSelection *ese;
927         float *fp, *newkey, *oldkey, nor[3];
928         int i, a, ototvert;
929         
930         /* this one also tests of edges are not in faces: */
931         /* eed->f2==0: not in face, f2==1: draw it */
932         /* eed->f1 : flag for dynaface (cylindertest, old engine) */
933         /* eve->f1 : flag for dynaface (sphere test, old engine) */
934         /* eve->f2 : being used in vertexnormals */
935         edge_drawflags(me, em);
936         
937         EM_stats_update(em);
938         
939         /* new Vertex block */
940         if(em->totvert==0) mvert= NULL;
941         else mvert= MEM_callocN(em->totvert*sizeof(MVert), "loadeditMesh vert");
942
943         /* new Edge block */
944         if(em->totedge==0) medge= NULL;
945         else medge= MEM_callocN(em->totedge*sizeof(MEdge), "loadeditMesh edge");
946         
947         /* new Face block */
948         if(em->totface==0) mface= NULL;
949         else mface= MEM_callocN(em->totface*sizeof(MFace), "loadeditMesh face");
950
951         /* lets save the old verts just in case we are actually working on
952          * a key ... we now do processing of the keys at the end */
953         oldverts= me->mvert;
954         ototvert= me->totvert;
955
956         /* don't free this yet */
957         CustomData_set_layer(&me->vdata, CD_MVERT, NULL);
958
959         /* free custom data */
960         CustomData_free(&me->vdata, me->totvert);
961         CustomData_free(&me->edata, me->totedge);
962         CustomData_free(&me->fdata, me->totface);
963
964         /* add new custom data */
965         me->totvert= em->totvert;
966         me->totedge= em->totedge;
967         me->totface= em->totface;
968
969         CustomData_copy(&em->vdata, &me->vdata, CD_MASK_MESH, CD_CALLOC, me->totvert);
970         CustomData_copy(&em->edata, &me->edata, CD_MASK_MESH, CD_CALLOC, me->totedge);
971         CustomData_copy(&em->fdata, &me->fdata, CD_MASK_MESH, CD_CALLOC, me->totface);
972
973         CustomData_add_layer(&me->vdata, CD_MVERT, CD_ASSIGN, mvert, me->totvert);
974         CustomData_add_layer(&me->edata, CD_MEDGE, CD_ASSIGN, medge, me->totedge);
975         CustomData_add_layer(&me->fdata, CD_MFACE, CD_ASSIGN, mface, me->totface);
976         mesh_update_customdata_pointers(me);
977
978         /* the vertices, use ->tmp.l as counter */
979         eve= em->verts.first;
980         a= 0;
981
982         while(eve) {
983                 VECCOPY(mvert->co, eve->co);
984
985                 mvert->mat_nr= 32767;  /* what was this for, halos? */
986                 
987                 /* vertex normal */
988                 VECCOPY(nor, eve->no);
989                 mul_v3_fl(nor, 32767.0);
990                 VECCOPY(mvert->no, nor);
991
992                 /* note: it used to remove me->dvert when it was not in use, cancelled
993                    that... annoying when you have a fresh vgroup */
994                 CustomData_from_em_block(&em->vdata, &me->vdata, eve->data, a);
995
996                 eve->tmp.l = a++;  /* counter */
997                         
998                 mvert->flag= 0;
999                 mvert->flag |= (eve->f & SELECT);
1000                 if (eve->h) mvert->flag |= ME_HIDE;
1001                 
1002                 mvert->bweight= (char)(255.0*eve->bweight);
1003
1004                 eve= eve->next;
1005                 mvert++;
1006         }
1007
1008         /* the edges */
1009         a= 0;
1010         eed= em->edges.first;
1011         while(eed) {
1012                 medge->v1= (unsigned int) eed->v1->tmp.l;
1013                 medge->v2= (unsigned int) eed->v2->tmp.l;
1014                 
1015                 medge->flag= (eed->f & SELECT) | ME_EDGERENDER;
1016                 if(eed->f2<2) medge->flag |= ME_EDGEDRAW;
1017                 if(eed->f2==0) medge->flag |= ME_LOOSEEDGE;
1018                 if(eed->sharp) medge->flag |= ME_SHARP;
1019                 if(eed->seam) medge->flag |= ME_SEAM;
1020                 if(eed->h & EM_FGON) medge->flag |= ME_FGON;    // different defines yes
1021                 if(eed->h & 1) medge->flag |= ME_HIDE;
1022                 
1023                 medge->crease= (char)(255.0*eed->crease);
1024                 medge->bweight= (char)(255.0*eed->bweight);
1025                 CustomData_from_em_block(&em->edata, &me->edata, eed->data, a);         
1026
1027                 eed->tmp.l = a++;
1028                 
1029                 medge++;
1030                 eed= eed->next;
1031         }
1032
1033         /* the faces */
1034         a = 0;
1035         efa= em->faces.first;
1036         efa_act= EM_get_actFace(em, 0);
1037         i = 0;
1038         me->act_face = -1;
1039         while(efa) {
1040                 mface= &((MFace *) me->mface)[i];
1041                 
1042                 mface->v1= (unsigned int) efa->v1->tmp.l;
1043                 mface->v2= (unsigned int) efa->v2->tmp.l;
1044                 mface->v3= (unsigned int) efa->v3->tmp.l;
1045                 if (efa->v4) mface->v4 = (unsigned int) efa->v4->tmp.l;
1046
1047                 mface->mat_nr= efa->mat_nr;
1048                 
1049                 mface->flag= efa->flag;
1050                 /* bit 0 of flag is already taken for smooth... */
1051                 
1052                 if(efa->h) {
1053                         mface->flag |= ME_HIDE;
1054                         mface->flag &= ~ME_FACE_SEL;
1055                 } else {
1056                         if(efa->f & 1) mface->flag |= ME_FACE_SEL;
1057                         else mface->flag &= ~ME_FACE_SEL;
1058                 }
1059                 
1060                 /* mat_nr in vertex */
1061                 if(me->totcol>1) {
1062                         mvert= me->mvert+mface->v1;
1063                         if(mvert->mat_nr == (char)32767) mvert->mat_nr= mface->mat_nr;
1064                         mvert= me->mvert+mface->v2;
1065                         if(mvert->mat_nr == (char)32767) mvert->mat_nr= mface->mat_nr;
1066                         mvert= me->mvert+mface->v3;
1067                         if(mvert->mat_nr == (char)32767) mvert->mat_nr= mface->mat_nr;
1068                         if(mface->v4) {
1069                                 mvert= me->mvert+mface->v4;
1070                                 if(mvert->mat_nr == (char)32767) mvert->mat_nr= mface->mat_nr;
1071                         }
1072                 }
1073                         
1074                 /* watch: efa->e1->f2==0 means loose edge */ 
1075                         
1076                 if(efa->e1->f2==1) {
1077                         efa->e1->f2= 2;
1078                 }                       
1079                 if(efa->e2->f2==1) {
1080                         efa->e2->f2= 2;
1081                 }
1082                 if(efa->e3->f2==1) {
1083                         efa->e3->f2= 2;
1084                 }
1085                 if(efa->e4 && efa->e4->f2==1) {
1086                         efa->e4->f2= 2;
1087                 }
1088
1089                 CustomData_from_em_block(&em->fdata, &me->fdata, efa->data, i);
1090
1091                 /* no index '0' at location 3 or 4 */
1092                 test_index_face(mface, &me->fdata, i, efa->v4?4:3);
1093                 
1094                 if (efa_act == efa)
1095                         me->act_face = a;
1096
1097                 efa->tmp.l = a++;
1098                 i++;
1099                 efa= efa->next;
1100         }
1101
1102         /* patch hook indices and vertex parents */
1103         {
1104                 Object *ob;
1105                 ModifierData *md;
1106                 EditVert **vertMap = NULL;
1107                 int i,j;
1108
1109                 for (ob=G.main->object.first; ob; ob=ob->id.next) {
1110                         if (ob->parent==ob && ELEM(ob->partype, PARVERT1,PARVERT3)) {
1111                                 
1112                                 /* duplicate code from below, make it function later...? */
1113                                 if (!vertMap) {
1114                                         vertMap = MEM_callocN(sizeof(*vertMap)*ototvert, "vertMap");
1115                                         
1116                                         for (eve=em->verts.first; eve; eve=eve->next) {
1117                                                 if (eve->keyindex!=-1)
1118                                                         vertMap[eve->keyindex] = eve;
1119                                         }
1120                                 }
1121                                 if(ob->par1 < ototvert) {
1122                                         eve = vertMap[ob->par1];
1123                                         if(eve) ob->par1= eve->tmp.l;
1124                                 }
1125                                 if(ob->par2 < ototvert) {
1126                                         eve = vertMap[ob->par2];
1127                                         if(eve) ob->par2= eve->tmp.l;
1128                                 }
1129                                 if(ob->par3 < ototvert) {
1130                                         eve = vertMap[ob->par3];
1131                                         if(eve) ob->par3= eve->tmp.l;
1132                                 }
1133                                 
1134                         }
1135                         if (ob->data==me) {
1136                                 for (md=ob->modifiers.first; md; md=md->next) {
1137                                         if (md->type==eModifierType_Hook) {
1138                                                 HookModifierData *hmd = (HookModifierData*) md;
1139
1140                                                 if (!vertMap) {
1141                                                         vertMap = MEM_callocN(sizeof(*vertMap)*ototvert, "vertMap");
1142
1143                                                         for (eve=em->verts.first; eve; eve=eve->next) {
1144                                                                 if (eve->keyindex!=-1)
1145                                                                         vertMap[eve->keyindex] = eve;
1146                                                         }
1147                                                 }
1148                                                 
1149                                                 for (i=j=0; i<hmd->totindex; i++) {
1150                                                         if(hmd->indexar[i] < ototvert) {
1151                                                                 eve = vertMap[hmd->indexar[i]];
1152                                                                 
1153                                                                 if (eve) {
1154                                                                         hmd->indexar[j++] = eve->tmp.l;
1155                                                                 }
1156                                                         }
1157                                                         else j++;
1158                                                 }
1159
1160                                                 hmd->totindex = j;
1161                                         }
1162                                 }
1163                         }
1164                 }
1165
1166                 if (vertMap) MEM_freeN(vertMap);
1167         }
1168
1169         /* are there keys? */
1170         if(me->key) {
1171                 KeyBlock *currkey;
1172                 KeyBlock *actkey= BLI_findlink(&me->key->block, em->shapenr-1);
1173
1174                 float (*ofs)[3] = NULL;
1175
1176                 /* editing the base key should update others */
1177                 if(me->key->type==KEY_RELATIVE && oldverts) {
1178                         int act_is_basis = 0;
1179                         /* find if this key is a basis for any others */
1180                         for(currkey = me->key->block.first; currkey; currkey= currkey->next) {
1181                                 if(em->shapenr-1 == currkey->relative) {
1182                                         act_is_basis = 1;
1183                                         break;
1184                                 }
1185                         }
1186
1187                         if(act_is_basis) { /* active key is a base */
1188                                 i=0;
1189                                 ofs= MEM_callocN(sizeof(float) * 3 * em->totvert,  "currkey->data");
1190                                 eve= em->verts.first;
1191                                 mvert = me->mvert;
1192                                 while(eve) {
1193                                         VECSUB(ofs[i], mvert->co, oldverts[eve->keyindex].co);
1194                                         eve= eve->next;
1195                                         i++;
1196                                         mvert++;
1197                                 }
1198                         }
1199                 }
1200
1201
1202                 /* Lets reorder the key data so that things line up roughly
1203                  * with the way things were before editmode */
1204                 currkey = me->key->block.first;
1205                 while(currkey) {
1206                         int apply_offset = (ofs && (currkey != actkey) && (em->shapenr-1 == currkey->relative));
1207
1208                         fp= newkey= MEM_callocN(me->key->elemsize*em->totvert,  "currkey->data");
1209                         oldkey = currkey->data;
1210
1211                         eve= em->verts.first;
1212
1213                         i = 0;
1214                         mvert = me->mvert;
1215                         while(eve) {
1216                                 if (eve->keyindex >= 0 && eve->keyindex < currkey->totelem) { // valid old vertex
1217                                         if(currkey == actkey) {
1218                                                 if(actkey == me->key->refkey) {
1219                                                         VECCOPY(fp, mvert->co);
1220                                                 }
1221                                                 else {
1222                                                         VECCOPY(fp, mvert->co);
1223                                                         if(oldverts) {
1224                                                                 VECCOPY(mvert->co, oldverts[eve->keyindex].co);
1225                                                         }
1226                                                 }
1227                                         }
1228                                         else {
1229                                                 if(oldkey) {
1230                                                         VECCOPY(fp, oldkey + 3 * eve->keyindex);
1231                                                 }
1232                                         }
1233                                 }
1234                                 else {
1235                                         VECCOPY(fp, mvert->co);
1236                                 }
1237
1238                                 /* propagate edited basis offsets to other shapes */
1239                                 if(apply_offset) {
1240                                         VECADD(fp, fp, ofs[i]);
1241                                 }
1242
1243                                 fp+= 3;
1244                                 ++i;
1245                                 ++mvert;
1246                                 eve= eve->next;
1247                         }
1248                         currkey->totelem= em->totvert;
1249                         if(currkey->data) MEM_freeN(currkey->data);
1250                         currkey->data = newkey;
1251                         
1252                         currkey= currkey->next;
1253                 }
1254
1255                 if(ofs) MEM_freeN(ofs);
1256         }
1257
1258         if(oldverts) MEM_freeN(oldverts);
1259         
1260         i = 0;
1261         for(ese=em->selected.first; ese; ese=ese->next) i++;
1262         me->totselect = i;
1263         if(i==0) mselect= NULL;
1264         else mselect= MEM_callocN(i*sizeof(MSelect), "loadeditMesh selections");
1265         
1266         if(me->mselect) MEM_freeN(me->mselect);
1267         me->mselect= mselect;
1268         
1269         for(ese=em->selected.first; ese; ese=ese->next){
1270                 mselect->type = ese->type;
1271                 if(ese->type == EDITVERT) mselect->index = ((EditVert*)ese->data)->tmp.l;
1272                 else if(ese->type == EDITEDGE) mselect->index = ((EditEdge*)ese->data)->tmp.l;
1273                 else if(ese->type == EDITFACE) mselect->index = ((EditFace*)ese->data)->tmp.l;
1274                 mselect++;
1275         }
1276         
1277         /* to be sure: clear ->tmp.l pointers */
1278         eve= em->verts.first;
1279         while(eve) {
1280                 eve->tmp.l = 0;
1281                 eve= eve->next;
1282         }
1283         
1284         eed= em->edges.first;
1285         while(eed) { 
1286                 eed->tmp.l = 0;
1287                 eed= eed->next;
1288         }
1289         
1290         efa= em->faces.first;
1291         while(efa) {
1292                 efa->tmp.l = 0;
1293                 efa= efa->next;
1294         }
1295         
1296         /* remake softbody of all users */
1297         if(me->id.us>1) {
1298                 Base *base;
1299                 for(base= scene->base.first; base; base= base->next)
1300                         if(base->object->data==me)
1301                                 base->object->recalc |= OB_RECALC_DATA;
1302         }
1303
1304         mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL);
1305 }
1306
1307 void remake_editMesh(Scene *scene, Object *ob)
1308 {
1309         make_editMesh(scene, ob);
1310         DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
1311         BIF_undo_push("Undo all changes");
1312 }
1313
1314 /* *************** Operator: separate parts *************/
1315
1316 static EnumPropertyItem prop_separate_types[] = {
1317         {0, "SELECTED", 0, "Selection", ""},
1318         {1, "MATERIAL", 0, "By Material", ""},
1319         {2, "LOOSE", 0, "By loose parts", ""},
1320         {0, NULL, 0, NULL, NULL}
1321 };
1322
1323 /* return 1: success */
1324 static int mesh_separate_selected(Main *bmain, Scene *scene, Base *editbase)
1325 {
1326         EditMesh *em, *emnew;
1327         EditVert *eve, *v1;
1328         EditEdge *eed, *e1;
1329         EditFace *efa, *f1;
1330         Object *obedit;
1331         Mesh *me, *menew;
1332         Base *basenew;
1333         
1334         if(editbase==NULL) return 0;
1335         
1336         obedit= editbase->object;
1337         me= obedit->data;
1338         em= BKE_mesh_get_editmesh(me);
1339         if(me->key) {
1340                 error("Can't separate with vertex keys");
1341                 BKE_mesh_end_editmesh(me, em);
1342                 return 0;
1343         }
1344         
1345         if(em->selected.first) 
1346                 BLI_freelistN(&(em->selected)); /* clear the selection order */
1347                 
1348         EM_selectmode_set(em);  // enforce full consistent selection flags 
1349         
1350         EM_stats_update(em);
1351         
1352         if(em->totvertsel==0) {
1353                 BKE_mesh_end_editmesh(me, em);
1354                 return 0;
1355         }
1356         
1357         /* we are going to work as follows:
1358          * 1. add a linked duplicate object: this will be the new one, we remember old pointer
1359          * 2. give new object empty mesh and put in editmode
1360          * 3: do a split if needed on current editmesh.
1361          * 4. copy over: all NOT selected verts, edges, faces
1362          * 5. call load_editMesh() on the new object
1363          */
1364         
1365         /* 1 */
1366         basenew= ED_object_add_duplicate(bmain, scene, editbase, 0);    /* 0 = fully linked */
1367         ED_base_object_select(basenew, BA_DESELECT);
1368         
1369         /* 2 */
1370         basenew->object->data= menew= add_mesh(me->id.name+2);  /* empty */
1371         assign_matarar(basenew->object, give_matarar(obedit), *give_totcolp(obedit)); /* new in 2.5 */
1372         me->id.us--;
1373         make_editMesh(scene, basenew->object);
1374         emnew= menew->edit_mesh;
1375         CustomData_copy(&em->vdata, &emnew->vdata, CD_MASK_EDITMESH, CD_DEFAULT, 0);
1376         CustomData_copy(&em->edata, &emnew->edata, CD_MASK_EDITMESH, CD_DEFAULT, 0);
1377         CustomData_copy(&em->fdata, &emnew->fdata, CD_MASK_EDITMESH, CD_DEFAULT, 0);
1378         
1379         /* 3 */
1380         /* SPLIT: first make duplicate */
1381         adduplicateflag(em, SELECT);
1382         /* SPLIT: old faces have 3x flag 128 set, delete these ones */
1383         delfaceflag(em, 128);
1384         /* since we do tricky things with verts/edges/faces, this makes sure all is selected coherent */
1385         EM_selectmode_set(em);
1386         
1387         /* 4 */
1388         /* move over: everything that is selected */
1389         for(eve= em->verts.first; eve; eve= v1) {
1390                 v1= eve->next;
1391                 if(eve->f & SELECT) {
1392                         BLI_remlink(&em->verts, eve);
1393                         BLI_addtail(&emnew->verts, eve);
1394                 }
1395         }
1396         
1397         for(eed= em->edges.first; eed; eed= e1) {
1398                 e1= eed->next;
1399                 if(eed->f & SELECT) {
1400                         BLI_remlink(&em->edges, eed);
1401                         BLI_addtail(&emnew->edges, eed);
1402                 }
1403         }
1404         
1405         for(efa= em->faces.first; efa; efa= f1) {
1406                 f1= efa->next;
1407                 if (efa == em->act_face && (efa->f & SELECT)) {
1408                         EM_set_actFace(em, NULL);
1409                 }
1410
1411                 if(efa->f & SELECT) {
1412                         BLI_remlink(&em->faces, efa);
1413                         BLI_addtail(&emnew->faces, efa);
1414                 }
1415         }
1416
1417         /* 5 */
1418         load_editMesh(scene, basenew->object);
1419         free_editMesh(emnew);
1420         MEM_freeN(menew->edit_mesh);
1421         menew->edit_mesh= NULL;
1422         
1423         /* hashedges are invalid now, make new! */
1424         editMesh_set_hash(em);
1425
1426         DAG_id_flush_update(&obedit->id, OB_RECALC_DATA);       
1427         DAG_id_flush_update(&basenew->object->id, OB_RECALC_DATA);      
1428
1429         BKE_mesh_end_editmesh(me, em);
1430
1431         return 1;
1432 }
1433
1434 /* return 1: success */
1435 static int mesh_separate_material(Main *bmain, Scene *scene, Base *editbase)
1436 {
1437         Mesh *me= editbase->object->data;
1438         EditMesh *em= BKE_mesh_get_editmesh(me);
1439         unsigned char curr_mat;
1440         
1441         for (curr_mat = 1; curr_mat < editbase->object->totcol; ++curr_mat) {
1442                 /* clear selection, we're going to use that to select material group */
1443                 EM_clear_flag_all(em, SELECT);
1444                 /* select the material */
1445                 EM_select_by_material(em, curr_mat);
1446                 /* and now separate */
1447                 if(0==mesh_separate_selected(bmain, scene, editbase)) {
1448                         BKE_mesh_end_editmesh(me, em);
1449                         return 0;
1450                 }
1451         }
1452
1453         BKE_mesh_end_editmesh(me, em);
1454         return 1;
1455 }
1456
1457 /* return 1: success */
1458 static int mesh_separate_loose(Main *bmain, Scene *scene, Base *editbase)
1459 {
1460         Mesh *me;
1461         EditMesh *em;
1462         int doit= 1;
1463         
1464         me= editbase->object->data;
1465         em= BKE_mesh_get_editmesh(me);
1466         
1467         if(me->key) {
1468                 error("Can't separate with vertex keys");
1469                 BKE_mesh_end_editmesh(me, em);
1470                 return 0;
1471         }
1472         
1473         EM_clear_flag_all(em, SELECT);
1474
1475         while(doit) {
1476                 /* Select a random vert to start with */
1477                 EditVert *eve;
1478                 int tot;
1479
1480                 /* check if all verts that are visible have been done */
1481                 for(eve=em->verts.first; eve; eve= eve->next)
1482                         if(!eve->h) break;
1483                 if(eve==NULL) break; /* only hidden verts left, quit early */
1484
1485                 /* first non hidden vert */
1486                 eve->f |= SELECT;
1487                 
1488                 selectconnected_mesh_all(em);
1489                 
1490                 /* don't separate the very last part */
1491                 for(eve=em->verts.first; eve; eve= eve->next)
1492                         if((eve->f & SELECT)==0) break;
1493                 if(eve==NULL) break;
1494
1495                 tot= BLI_countlist(&em->verts);
1496
1497                 /* and now separate */
1498                 doit= mesh_separate_selected(bmain, scene, editbase);
1499
1500                 /* with hidden verts this can happen */
1501                 if(tot == BLI_countlist(&em->verts))
1502                         break;
1503         }
1504
1505         BKE_mesh_end_editmesh(me, em);
1506         return 1;
1507 }
1508
1509
1510 static int mesh_separate_exec(bContext *C, wmOperator *op)
1511 {
1512         Main *bmain= CTX_data_main(C);
1513         Scene *scene= CTX_data_scene(C);
1514         Base *base= CTX_data_active_base(C);
1515         int retval= 0, type= RNA_enum_get(op->ptr, "type");
1516         
1517         if(type == 0)
1518                 retval= mesh_separate_selected(bmain, scene, base);
1519         else if(type == 1)
1520                 retval= mesh_separate_material(bmain, scene, base);
1521         else if(type == 2)
1522                 retval= mesh_separate_loose(bmain, scene, base);
1523            
1524         if(retval) {
1525                 WM_event_add_notifier(C, NC_GEOM|ND_DATA, base->object->data);
1526                 return OPERATOR_FINISHED;
1527         }
1528         return OPERATOR_CANCELLED;
1529 }
1530
1531 void MESH_OT_separate(wmOperatorType *ot)
1532 {
1533         /* identifiers */
1534         ot->name= "Separate";
1535         ot->description= "Separate selected geometry into a new mesh";
1536         ot->idname= "MESH_OT_separate";
1537         
1538         /* api callbacks */
1539         ot->invoke= WM_menu_invoke;
1540         ot->exec= mesh_separate_exec;
1541         ot->poll= ED_operator_editmesh;
1542         
1543         /* flags */
1544         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1545         
1546         ot->prop= RNA_def_enum(ot->srna, "type", prop_separate_types, 0, "Type", "");
1547 }
1548
1549
1550 /* ******************************************** */
1551
1552 /* *************** UNDO ***************************** */
1553 /* new mesh undo, based on pushing editmesh data itself */
1554 /* reuses same code as for global and curve undo... unify that (ton) */
1555
1556 /* only one 'hack', to save memory it doesn't store the first push, but does a remake editmesh */
1557
1558 /* a compressed version of editmesh data */
1559
1560 typedef struct EditVertC
1561 {
1562         float no[3];
1563         float co[3];
1564         unsigned char f, h;
1565         short bweight;
1566         int keyindex;
1567 } EditVertC;
1568
1569 typedef struct EditEdgeC
1570 {
1571         int v1, v2;
1572         unsigned char f, h, seam, sharp, pad;
1573         short crease, bweight, fgoni;
1574 } EditEdgeC;
1575
1576 typedef struct EditFaceC
1577 {
1578         int v1, v2, v3, v4;
1579         unsigned char flag, f, h, fgonf, pad1;
1580         short mat_nr;
1581 } EditFaceC;
1582
1583 typedef struct EditSelectionC{
1584         short type;
1585         int index;
1586 }EditSelectionC;
1587
1588 typedef struct UndoMesh {
1589         EditVertC *verts;
1590         EditEdgeC *edges;
1591         EditFaceC *faces;
1592         EditSelectionC *selected;
1593         int totvert, totedge, totface, totsel;
1594         int selectmode, shapenr;
1595         RetopoPaintData *retopo_paint_data;
1596         char retopo_mode;
1597         CustomData vdata, edata, fdata;
1598 } UndoMesh;
1599
1600 /* for callbacks */
1601
1602 static void free_undoMesh(void *umv)
1603 {
1604         UndoMesh *um= umv;
1605         
1606         if(um->verts) MEM_freeN(um->verts);
1607         if(um->edges) MEM_freeN(um->edges);
1608         if(um->faces) MEM_freeN(um->faces);
1609         if(um->selected) MEM_freeN(um->selected);
1610 // XXX  if(um->retopo_paint_data) retopo_free_paint_data(um->retopo_paint_data);
1611         CustomData_free(&um->vdata, um->totvert);
1612         CustomData_free(&um->edata, um->totedge);
1613         CustomData_free(&um->fdata, um->totface);
1614         MEM_freeN(um);
1615 }
1616
1617 static void *editMesh_to_undoMesh(void *emv)
1618 {
1619         EditMesh *em= (EditMesh *)emv;
1620         UndoMesh *um;
1621         EditVert *eve;
1622         EditEdge *eed;
1623         EditFace *efa;
1624         EditSelection *ese;
1625         EditVertC *evec=NULL;
1626         EditEdgeC *eedc=NULL;
1627         EditFaceC *efac=NULL;
1628         EditSelectionC *esec=NULL;
1629         int a;
1630
1631         um= MEM_callocN(sizeof(UndoMesh), "undomesh");
1632         
1633         um->selectmode = em->selectmode;
1634         um->shapenr = em->shapenr;
1635         
1636         for(eve=em->verts.first; eve; eve= eve->next) um->totvert++;
1637         for(eed=em->edges.first; eed; eed= eed->next) um->totedge++;
1638         for(efa=em->faces.first; efa; efa= efa->next) um->totface++;
1639         for(ese=em->selected.first; ese; ese=ese->next) um->totsel++; 
1640         /* malloc blocks */
1641         
1642         if(um->totvert) evec= um->verts= MEM_callocN(um->totvert*sizeof(EditVertC), "allvertsC");
1643         if(um->totedge) eedc= um->edges= MEM_callocN(um->totedge*sizeof(EditEdgeC), "alledgesC");
1644         if(um->totface) efac= um->faces= MEM_callocN(um->totface*sizeof(EditFaceC), "allfacesC");
1645         if(um->totsel) esec= um->selected= MEM_callocN(um->totsel*sizeof(EditSelectionC), "allselections");
1646
1647         if(um->totvert) CustomData_copy(&em->vdata, &um->vdata, CD_MASK_EDITMESH, CD_CALLOC, um->totvert);
1648         if(um->totedge) CustomData_copy(&em->edata, &um->edata, CD_MASK_EDITMESH, CD_CALLOC, um->totedge);
1649         if(um->totface) CustomData_copy(&em->fdata, &um->fdata, CD_MASK_EDITMESH, CD_CALLOC, um->totface);
1650         
1651         /* now copy vertices */
1652         a = 0;
1653         for(eve=em->verts.first; eve; eve= eve->next, evec++, a++) {
1654                 VECCOPY(evec->co, eve->co);
1655                 VECCOPY(evec->no, eve->no);
1656
1657                 evec->f= eve->f;
1658                 evec->h= eve->h;
1659                 evec->keyindex= eve->keyindex;
1660                 eve->tmp.l = a; /*store index*/
1661                 evec->bweight= (short)(eve->bweight*255.0);
1662
1663                 CustomData_from_em_block(&em->vdata, &um->vdata, eve->data, a);
1664         }
1665         
1666         /* copy edges */
1667         a = 0;
1668         for(eed=em->edges.first; eed; eed= eed->next, eedc++, a++)  {
1669                 eedc->v1= (int)eed->v1->tmp.l;
1670                 eedc->v2= (int)eed->v2->tmp.l;
1671                 eedc->f= eed->f;
1672                 eedc->h= eed->h;
1673                 eedc->seam= eed->seam;
1674                 eedc->sharp= eed->sharp;
1675                 eedc->crease= (short)(eed->crease*255.0);
1676                 eedc->bweight= (short)(eed->bweight*255.0);
1677                 eedc->fgoni= eed->fgoni;
1678                 eed->tmp.l = a; /*store index*/
1679                 CustomData_from_em_block(&em->edata, &um->edata, eed->data, a);
1680         
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                 efa->tmp.l = a; /*store index*/
1699
1700                 CustomData_from_em_block(&em->fdata, &um->fdata, efa->data, a);
1701         }
1702         
1703         a = 0;
1704         for(ese=em->selected.first; ese; ese=ese->next, esec++){
1705                 esec->type = ese->type;
1706                 if(ese->type == EDITVERT) a = esec->index = ((EditVert*)ese->data)->tmp.l; 
1707                 else if(ese->type == EDITEDGE) a = esec->index = ((EditEdge*)ese->data)->tmp.l; 
1708                 else if(ese->type == EDITFACE) a = esec->index = ((EditFace*)ese->data)->tmp.l;
1709         }
1710
1711 // XXX  um->retopo_paint_data= retopo_paint_data_copy(em->retopo_paint_data);
1712 //      um->retopo_mode= scene->toolsettings->retopo_mode;
1713         
1714         return um;
1715 }
1716
1717 static void undoMesh_to_editMesh(void *umv, void *emv)
1718 {
1719         EditMesh *em= (EditMesh *)emv;
1720         UndoMesh *um= (UndoMesh *)umv;
1721         EditVert *eve, **evar=NULL;
1722         EditEdge *eed;
1723         EditFace *efa;
1724         EditSelection *ese;
1725         EditVertC *evec;
1726         EditEdgeC *eedc;
1727         EditFaceC *efac;
1728         EditSelectionC *esec;
1729         int a=0;
1730
1731         free_editMesh(em);
1732         
1733         /* malloc blocks */
1734         memset(em, 0, sizeof(EditMesh));
1735                 
1736         em->selectmode = um->selectmode;
1737         em->shapenr = um->shapenr;
1738         
1739         init_editmesh_fastmalloc(em, um->totvert, um->totedge, um->totface);
1740
1741         CustomData_free(&em->vdata, 0);
1742         CustomData_free(&em->edata, 0);
1743         CustomData_free(&em->fdata, 0);
1744
1745         CustomData_copy(&um->vdata, &em->vdata, CD_MASK_EDITMESH, CD_CALLOC, 0);
1746         CustomData_copy(&um->edata, &em->edata, CD_MASK_EDITMESH, CD_CALLOC, 0);
1747         CustomData_copy(&um->fdata, &em->fdata, CD_MASK_EDITMESH, CD_CALLOC, 0);
1748
1749         /* now copy vertices */
1750
1751         if(um->totvert) evar= MEM_mallocN(um->totvert*sizeof(EditVert *), "vertex ar");
1752         for(a=0, evec= um->verts; a<um->totvert; a++, evec++) {
1753                 eve= addvertlist(em, evec->co, NULL);
1754                 evar[a]= eve;
1755
1756                 VECCOPY(eve->no, evec->no);
1757                 eve->f= evec->f;
1758                 eve->h= evec->h;
1759                 eve->keyindex= evec->keyindex;
1760                 eve->bweight= ((float)evec->bweight)/255.0f;
1761
1762                 CustomData_to_em_block(&um->vdata, &em->vdata, a, &eve->data);
1763         }
1764
1765         /* copy edges */
1766         for(a=0, eedc= um->edges; a<um->totedge; a++, eedc++) {
1767                 eed= addedgelist(em, evar[eedc->v1], evar[eedc->v2], NULL);
1768
1769                 eed->f= eedc->f;
1770                 eed->h= eedc->h;
1771                 eed->seam= eedc->seam;
1772                 eed->sharp= eedc->sharp;
1773                 eed->fgoni= eedc->fgoni;
1774                 eed->crease= ((float)eedc->crease)/255.0f;
1775                 eed->bweight= ((float)eedc->bweight)/255.0f;
1776                 CustomData_to_em_block(&um->edata, &em->edata, a, &eed->data);
1777         }
1778         
1779         /* copy faces */
1780         for(a=0, efac= um->faces; a<um->totface; a++, efac++) {
1781                 if(efac->v4 != -1)
1782                         efa= addfacelist(em, evar[efac->v1], evar[efac->v2], evar[efac->v3], evar[efac->v4], NULL, NULL);
1783                 else 
1784                         efa= addfacelist(em, evar[efac->v1], evar[efac->v2], evar[efac->v3], NULL, NULL ,NULL);
1785
1786                 efa->mat_nr= efac->mat_nr;
1787                 efa->flag= efac->flag;
1788                 efa->f= efac->f;
1789                 efa->h= efac->h;
1790                 efa->fgonf= efac->fgonf;
1791                 
1792                 CustomData_to_em_block(&um->fdata, &em->fdata, a, &efa->data);
1793         }
1794         
1795         end_editmesh_fastmalloc();
1796         if(evar) MEM_freeN(evar);
1797         
1798         em->totvert = um->totvert;
1799         em->totedge = um->totedge;
1800         em->totface = um->totface;
1801         /*restore stored editselections*/
1802         if(um->totsel){
1803                 EM_init_index_arrays(em, 1,1,1);
1804                 for(a=0, esec= um->selected; a<um->totsel; a++, esec++){
1805                         ese = MEM_callocN(sizeof(EditSelection), "Edit Selection");
1806                         ese->type = esec->type;
1807                         if(ese->type == EDITVERT) ese->data = EM_get_vert_for_index(esec->index); else
1808                         if(ese->type == EDITEDGE) ese->data = EM_get_edge_for_index(esec->index); else
1809                         if(ese->type == EDITFACE) ese->data = EM_get_face_for_index(esec->index);
1810                         BLI_addtail(&(em->selected),ese);
1811                 }
1812                 EM_free_index_arrays();
1813         }
1814
1815         /* restore total selections */
1816         EM_nvertices_selected(em);
1817         EM_nedges_selected(em);
1818         EM_nfaces_selected(em);
1819
1820 // XXX  retopo_free_paint();
1821 //      em->retopo_paint_data= retopo_paint_data_copy(um->retopo_paint_data);
1822 //      scene->toolsettings->retopo_mode= um->retopo_mode;
1823 //      if(scene->toolsettings->retopo_mode) {
1824 // XXX          if(G.vd->depths) G.vd->depths->damaged= 1;
1825 //              retopo_queue_updates(G.vd);
1826 //              retopo_paint_view_update(G.vd);
1827 //      }
1828         
1829 }
1830
1831 static void *getEditMesh(bContext *C)
1832 {
1833         Object *obedit= CTX_data_edit_object(C);
1834         if(obedit && obedit->type==OB_MESH) {
1835                 Mesh *me= obedit->data;
1836                 return me->edit_mesh;
1837         }
1838         return NULL;
1839 }
1840
1841 /* and this is all the undo system needs to know */
1842 void undo_push_mesh(bContext *C, char *name)
1843 {
1844         undo_editmode_push(C, name, getEditMesh, free_undoMesh, undoMesh_to_editMesh, editMesh_to_undoMesh, NULL);
1845 }
1846
1847
1848
1849 /* *************** END UNDO *************/
1850
1851 static EditVert **g_em_vert_array = NULL;
1852 static EditEdge **g_em_edge_array = NULL;
1853 static EditFace **g_em_face_array = NULL;
1854
1855 void EM_init_index_arrays(EditMesh *em, int forVert, int forEdge, int forFace)
1856 {
1857         EditVert *eve;
1858         EditEdge *eed;
1859         EditFace *efa;
1860         int i;
1861
1862         if (forVert) {
1863                 em->totvert= BLI_countlist(&em->verts);
1864
1865                 if(em->totvert) {
1866                         g_em_vert_array = MEM_mallocN(sizeof(*g_em_vert_array)*em->totvert, "em_v_arr");
1867
1868                         for (i=0,eve=em->verts.first; eve; i++,eve=eve->next)
1869                                 g_em_vert_array[i] = eve;
1870                 }
1871         }
1872
1873         if (forEdge) {
1874                 em->totedge= BLI_countlist(&em->edges);
1875
1876                 if(em->totedge) {
1877                         g_em_edge_array = MEM_mallocN(sizeof(*g_em_edge_array)*em->totedge, "em_e_arr");
1878
1879                         for (i=0,eed=em->edges.first; eed; i++,eed=eed->next)
1880                                 g_em_edge_array[i] = eed;
1881                 }
1882         }
1883
1884         if (forFace) {
1885                 em->totface= BLI_countlist(&em->faces);
1886
1887                 if(em->totface) {
1888                         g_em_face_array = MEM_mallocN(sizeof(*g_em_face_array)*em->totface, "em_f_arr");
1889
1890                         for (i=0,efa=em->faces.first; efa; i++,efa=efa->next)
1891                                 g_em_face_array[i] = efa;
1892                 }
1893         }
1894 }
1895
1896 void EM_free_index_arrays(void)
1897 {
1898         if (g_em_vert_array) MEM_freeN(g_em_vert_array);
1899         if (g_em_edge_array) MEM_freeN(g_em_edge_array);
1900         if (g_em_face_array) MEM_freeN(g_em_face_array);
1901         g_em_vert_array = NULL;
1902         g_em_edge_array = NULL;
1903         g_em_face_array = NULL;
1904 }
1905
1906 EditVert *EM_get_vert_for_index(int index)
1907 {
1908         return g_em_vert_array?g_em_vert_array[index]:NULL;
1909 }
1910
1911 EditEdge *EM_get_edge_for_index(int index)
1912 {
1913         return g_em_edge_array?g_em_edge_array[index]:NULL;
1914 }
1915
1916 EditFace *EM_get_face_for_index(int index)
1917 {
1918         return g_em_face_array?g_em_face_array[index]:NULL;
1919 }
1920
1921 /* can we edit UV's for this mesh?*/
1922 int EM_texFaceCheck(EditMesh *em)
1923 {
1924         /* some of these checks could be a touch overkill */
1925         if (    (em) &&
1926                         (em->faces.first) &&
1927                         (CustomData_has_layer(&em->fdata, CD_MTFACE)))
1928                 return 1;
1929         return 0;
1930 }
1931
1932 /* can we edit colors for this mesh?*/
1933 int EM_vertColorCheck(EditMesh *em)
1934 {
1935         /* some of these checks could be a touch overkill */
1936         if (    (em) &&
1937                         (em->faces.first) &&
1938                         (CustomData_has_layer(&em->fdata, CD_MCOL)))
1939                 return 1;
1940         return 0;
1941 }
1942
1943
1944 void em_setup_viewcontext(bContext *C, ViewContext *vc)
1945 {
1946         view3d_set_viewcontext(C, vc);
1947         
1948         if(vc->obedit) {
1949                 Mesh *me= vc->obedit->data;
1950                 vc->em= me->edit_mesh;
1951         }
1952 }