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