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