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