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