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