Code Cleanup: style change only
[blender.git] / source / blender / bmesh / operators / mesh_conv.c
1 #include <string.h>
2
3 #include "MEM_guardedalloc.h"
4
5 #include "DNA_listBase.h"
6 #include "DNA_customdata_types.h"
7 #include "DNA_mesh_types.h"
8 #include "DNA_meshdata_types.h"
9 #include "DNA_modifier_types.h"
10 #include "DNA_key_types.h"
11 #include "DNA_object_types.h"
12 #include "DNA_scene_types.h"
13
14 #include "BKE_customdata.h" 
15 #include "BKE_mesh.h"
16 #include "BKE_global.h"
17 #include "BKE_DerivedMesh.h"
18 #include "BKE_cdderivedmesh.h"
19 #include "BKE_key.h"
20 #include "BKE_main.h"
21
22 #include "BLI_utildefines.h"
23 #include "BLI_listbase.h"
24 #include "BLI_math.h"
25 #include "BLI_edgehash.h"
26 #include "BLI_editVert.h"
27 #include "BLI_scanfill.h"
28 #include "BLI_array.h"
29 #include "BLI_utildefines.h"
30
31 #include "ED_mesh.h"
32
33 #include "mesh_intern.h"
34 #include "bmesh.h"
35 #include "bmesh_private.h"
36
37 /*
38  * MESH CONV.C
39  *
40  * This file contains functions
41  * for converting a Mesh
42  * into a Bmesh, and back again.
43  *
44 */
45
46 void mesh_to_bmesh_exec(BMesh *bm, BMOperator *op)
47 {
48         Object *ob = BMO_Get_Pnt(op, "object");
49         Mesh *me = BMO_Get_Pnt(op, "mesh");
50         MVert *mvert;
51         BLI_array_declare(verts);
52         MEdge *medge;
53         MLoop *ml;
54         MPoly *mpoly;
55         KeyBlock *actkey, *block;
56         BMVert *v, **vt=NULL, **verts = NULL;
57         BMEdge *e, **fedges=NULL, **et = NULL;
58         BMFace *f;
59         BMLoop *l;
60         BLI_array_declare(fedges);
61         float (*keyco)[3]= NULL;
62         int *keyi;
63         int set_key = BMO_Get_Int(op, "set_shapekey");
64         int totuv, i, j, allocsize[4] = {512, 512, 2048, 512};
65
66         if (!me || !me->totvert) return; /*sanity check*/
67         
68         vt = MEM_mallocN(sizeof(void**)*me->totvert, "mesh to bmesh vtable");
69
70         CustomData_copy(&me->vdata, &bm->vdata, CD_MASK_BMESH, CD_CALLOC, 0);
71         CustomData_copy(&me->edata, &bm->edata, CD_MASK_BMESH, CD_CALLOC, 0);
72         CustomData_copy(&me->ldata, &bm->ldata, CD_MASK_BMESH, CD_CALLOC, 0);
73         CustomData_copy(&me->pdata, &bm->pdata, CD_MASK_BMESH, CD_CALLOC, 0);
74         
75         /*make sure uv layer names are consistent*/
76         totuv = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY);
77         for (i=0; i<totuv; i++) {
78                 int li = CustomData_get_layer_index_n(&bm->pdata, CD_MTEXPOLY, i);
79                 CustomData_set_layer_name(&bm->ldata, CD_MLOOPUV, i, bm->pdata.layers[li].name);
80         }
81         
82         if (!CustomData_has_layer(&bm->edata, CD_CREASE))
83                 CustomData_add_layer(&bm->edata, CD_CREASE, CD_ASSIGN, NULL, 0);
84
85         if (!CustomData_has_layer(&bm->edata, CD_BWEIGHT))
86                 CustomData_add_layer(&bm->edata, CD_BWEIGHT, CD_ASSIGN, NULL, 0);
87
88         if (!CustomData_has_layer(&bm->vdata, CD_BWEIGHT))
89                 CustomData_add_layer(&bm->vdata, CD_BWEIGHT, CD_ASSIGN, NULL, 0);
90
91
92         if (me->key && ob->shapenr > me->key->totkey) {
93                 ob->shapenr = me->key->totkey-1;
94         }
95
96         actkey = ob_get_keyblock(ob);
97         if (actkey && actkey->totelem == me->totvert) {
98                 CustomData_add_layer(&bm->vdata, CD_SHAPE_KEYINDEX, CD_ASSIGN, NULL, 0);
99                 
100                 /*check if we need to generate unique ids for the shapekeys.
101                   this also exists in the file reading code, but is here for
102                   a sanity check*/
103                 if (!me->key->uidgen) {
104                         fprintf(stderr, "%s had to generate shape key uid's in a situation we shouldn't need to! (bmesh internal error)\n", __func__);
105                         me->key->uidgen = 1;
106                         for (block=me->key->block.first; block; block=block->next) {
107                                 block->uid = me->key->uidgen++;
108                         }
109                 }
110
111                 keyco= actkey->data;
112                 bm->shapenr= ob->shapenr;
113                 for (i=0, block=me->key->block.first; block; block=block->next, i++) {
114                         CustomData_add_layer_named(&bm->vdata, CD_SHAPEKEY, 
115                                          CD_ASSIGN, NULL, 0, block->name);
116                         
117                         j = CustomData_get_layer_index_n(&bm->vdata, CD_SHAPEKEY, i);
118                         bm->vdata.layers[j].uid = block->uid;
119                 }
120         }
121         else if (actkey) {
122                 printf("shapekey<->mesh mismatch!\n");
123         }
124         
125         CustomData_bmesh_init_pool(&bm->vdata, allocsize[0]);
126         CustomData_bmesh_init_pool(&bm->edata, allocsize[1]);
127         CustomData_bmesh_init_pool(&bm->ldata, allocsize[2]);
128         CustomData_bmesh_init_pool(&bm->pdata, allocsize[3]);
129
130         for (i=0, mvert = me->mvert; i<me->totvert; i++, mvert++) {
131                 v = BM_Make_Vert(bm, keyco&&set_key ? keyco[i] : mvert->co, NULL);
132                 BM_SetIndex(v, i); /* set_ok */
133                 vt[i] = v;
134
135                 /*transfer flags*/
136                 v->head.hflag = BM_Vert_Flag_From_MEFlag(mvert->flag);
137
138                 /*this is necassary for selection counts to work properly*/
139                 if (BM_TestHFlag(v, BM_SELECT)) BM_Select_Vert(bm, v, TRUE);
140
141                 normal_short_to_float_v3(v->no, mvert->no);
142
143                 BM_SetCDf(&bm->vdata, v, CD_BWEIGHT, (float)mvert->bweight / 255.0f);
144
145                 /*Copy Custom Data*/
146                 CustomData_to_bmesh_block(&me->vdata, &bm->vdata, i, &v->head.data);
147
148                 /*set shapekey data*/
149                 if (me->key) {
150                         /*set shape key original index*/
151                         keyi = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_SHAPE_KEYINDEX);
152                         if (keyi) {
153                                 *keyi = i;
154                         }
155                         
156                         for (block=me->key->block.first, j=0; block; block=block->next, j++) {
157                                 float *co = CustomData_bmesh_get_n(&bm->vdata, v->head.data, 
158                                                                    CD_SHAPEKEY, j);
159                                 if (co)
160                                         copy_v3_v3(co, ((float*)block->data)+3*i);
161                         }
162                 }
163         }
164
165         bm->elem_index_dirty &= ~BM_VERT; /* added in order, clear dirty flag */
166
167         if (!me->totedge) {
168                 MEM_freeN(vt);
169                 return;
170         }
171
172         et = MEM_mallocN(sizeof(void**)*me->totedge, "mesh to bmesh etable");
173
174         medge = me->medge;
175         for (i=0; i<me->totedge; i++, medge++) {
176                 e = BM_Make_Edge(bm, vt[medge->v1], vt[medge->v2], NULL, 0);
177                 BM_SetIndex(e, i); /* set_ok */
178                 et[i] = e;
179
180                 /* transfer flags */
181                 e->head.hflag = BM_Edge_Flag_From_MEFlag(medge->flag);
182
183                 /* this is necassary for selection counts to work properly */
184                 if (BM_TestHFlag(e, BM_SELECT)) BM_Select(bm, e, TRUE);
185                 
186                 /*Copy Custom Data*/
187                 CustomData_to_bmesh_block(&me->edata, &bm->edata, i, &e->head.data);
188                 
189                 BM_SetCDf(&bm->edata, e, CD_CREASE, (float)medge->crease / 255.0f);
190                 BM_SetCDf(&bm->edata, e, CD_BWEIGHT, (float)medge->bweight / 255.0f);
191         }
192
193         bm->elem_index_dirty &= ~BM_EDGE; /* added in order, clear dirty flag */
194         
195         if (!me->totpoly) {
196                 MEM_freeN(vt);
197                 MEM_freeN(et);
198                 return;
199         }
200
201         mpoly = me->mpoly;
202         for (i=0; i<me->totpoly; i++, mpoly++) {
203                 BMIter iter;
204
205                 BLI_array_empty(fedges);
206                 BLI_array_empty(verts);
207
208                 BLI_array_growitems(fedges, mpoly->totloop);
209                 BLI_array_growitems(verts, mpoly->totloop);
210
211                 for (j=0; j<mpoly->totloop; j++) {
212                         ml = &me->mloop[mpoly->loopstart+j];
213                         v = vt[ml->v];
214                         e = et[ml->e];
215
216                         fedges[j] = e;
217                         verts[j] = v;
218                 }
219                 
220                 /* not sure what this block is supposed to do,
221                  * but its unused. so commenting - campbell */
222 #if 0
223                 {
224                         BMVert *v1, *v2;
225                         v1 = vt[me->mloop[mpoly->loopstart].v];
226                         v2 = vt[me->mloop[mpoly->loopstart+1].v];
227
228                         if (v1 == fedges[0]->v1) {
229                                 v2 = fedges[0]->v2;
230                         }
231                         else {
232                                 v1 = fedges[0]->v2;
233                                 v2 = fedges[0]->v1;
234                         }
235                 }
236 #endif
237
238                 f = BM_Make_Face(bm, verts, fedges, mpoly->totloop, 0);
239
240                 if (!f) {
241                         printf("%s: Warning! Bad face in mesh"
242                                " \"%s\" at index %d!, skipping\n",
243                                __func__, me->id.name+2, i);
244                         continue;
245                 }
246
247                 /* dont use 'i' since we may have skipped the face */
248                 BM_SetIndex(f, bm->totface-1); /* set_ok */
249
250                 /*transfer flags*/
251                 f->head.hflag = BM_Face_Flag_From_MEFlag(mpoly->flag);
252
253                 /*this is necassary for selection counts to work properly*/
254                 if (BM_TestHFlag(f, BM_SELECT)) BM_Select(bm, f, TRUE);
255
256                 f->mat_nr = mpoly->mat_nr;
257                 if (i == me->act_face) bm->act_face = f;
258
259                 j = 0;
260                 BM_ITER_INDEX(l, &iter, bm, BM_LOOPS_OF_FACE, f, j) {
261                         /* Save index of correspsonding MLoop */
262                         BM_SetIndex(l, mpoly->loopstart+j); /* set_loop */
263                 }
264
265                 /*Copy Custom Data*/
266                 CustomData_to_bmesh_block(&me->pdata, &bm->pdata, i, &f->head.data);
267         }
268
269         bm->elem_index_dirty &= ~BM_FACE; /* added in order, clear dirty flag */
270
271         {
272                 BMIter fiter;
273                 BMIter liter;
274                 
275                 /* Copy over loop CustomData. Doing this in a separate loop isn't necessary
276                    but is an optimization, to avoid copying a bunch of interpolated customdata
277                    for each BMLoop (from previous BMLoops using the same edge), always followed
278                    by freeing the interpolated data and overwriting it with data from the Mesh. */
279                 BM_ITER(f, &fiter, bm, BM_FACES_OF_MESH, NULL) {
280                         BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, f) {
281                                 int li = BM_GetIndex(l);
282                                 CustomData_to_bmesh_block(&me->ldata, &bm->ldata, li, &l->head.data);
283                                 BM_SetIndex(l, 0); /* set_loop */
284                         }
285                 }
286         }
287
288         if (me->mselect && me->totselect != 0) {
289                 BMIter iter;
290                 BMVert *vertex;
291                 BMEdge *edge;
292                 BMFace *face;
293                 BMVert **vertex_array = MEM_callocN(sizeof(BMVert *) * bm->totvert,
294                                                   "Selection Conversion Vertex Pointer Array");
295                 BMEdge **edge_array = MEM_callocN(sizeof(BMEdge *) * bm->totedge,
296                                                 "Selection Conversion Edge Pointer Array");
297                 BMFace **face_array = MEM_callocN(sizeof(BMFace *) * bm->totface,
298                                                 "Selection Conversion Face Pointer Array");
299
300                 for (i = 0, vertex = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
301                     vertex; i++, vertex = BMIter_Step(&iter))
302                 {
303                         vertex_array[i] = vertex;
304                 }
305
306                 for (i = 0, edge = BMIter_New(&iter, bm, BM_EDGES_OF_MESH, NULL);
307                     edge; i++, edge = BMIter_Step(&iter))
308                 {
309                         edge_array[i] = edge;
310                 }
311
312                 for (i = 0, face = BMIter_New(&iter, bm, BM_FACES_OF_MESH, NULL);
313                     face; i++, face = BMIter_Step(&iter))
314                 {
315                         face_array[i] = face;
316                 }
317
318                 if (me->mselect) {
319                         for (i = 0; i < me->totselect; i++) {
320                                 if (me->mselect[i].type == ME_VSEL) {
321                                         BM_store_selection(bm, vertex_array[me->mselect[i].index]);
322                                 }
323                                 else if (me->mselect[i].type == ME_ESEL) {
324                                         BM_store_selection(bm, edge_array[me->mselect[i].index]);
325                                 }
326                                 else if (me->mselect[i].type == ME_FSEL) {
327                                         BM_store_selection(bm, face_array[me->mselect[i].index]);
328                                 }
329                         }
330                 }
331                 else {
332                         me->totselect= 0;
333                 }
334
335                 MEM_freeN(vertex_array);
336                 MEM_freeN(edge_array);
337                 MEM_freeN(face_array);
338         }
339         else {
340                 me->totselect = 0;
341                 if (me->mselect) {
342                         MEM_freeN(me->mselect);
343                         me->mselect = NULL;
344                 }
345         }
346
347         BLI_array_free(fedges);
348         BLI_array_free(verts);
349         
350         MEM_freeN(vt);
351         MEM_freeN(et);
352 }
353
354 void object_load_bmesh_exec(BMesh *bm, BMOperator *op)
355 {
356         Object *ob = BMO_Get_Pnt(op, "object");
357         /* Scene *scene = BMO_Get_Pnt(op, "scene"); */
358         Mesh *me = ob->data;
359
360         BMO_CallOpf(bm, "bmesh_to_mesh mesh=%p object=%p notesselation=%i", me, ob, TRUE);
361 }
362
363
364 static BMVert **bmesh_to_mesh_vertex_map(BMesh *bm, int ototvert)
365 {
366         BMVert **vertMap = NULL;
367         BMVert *eve;
368         int index;
369         int i= 0;
370         BMIter iter;
371
372         /* caller needs to ensure this */
373         BLI_assert(ototvert > 0);
374
375         vertMap = MEM_callocN(sizeof(*vertMap)*ototvert, "vertMap");
376         if (CustomData_has_layer(&bm->vdata, CD_SHAPE_KEYINDEX)) {
377                 int *keyi;
378                 BM_ITER(eve, &iter, bm, BM_VERTS_OF_MESH, NULL) {
379                         keyi = CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_SHAPE_KEYINDEX);
380                         if (keyi) {
381                                 if (((index= *keyi) != ORIGINDEX_NONE) && (index < ototvert)) {
382                                         vertMap[index] = eve;
383                                 }
384                         }
385                         else {
386                                 if (i < ototvert) {
387                                         vertMap[i] = eve;
388                                 }
389                         }
390                         i++;
391                 }
392         }
393         else {
394                 BM_ITER(eve, &iter, bm, BM_VERTS_OF_MESH, NULL) {
395                         if (i < ototvert) {
396                                 vertMap[i] = eve;
397                         }
398                         else {
399                                 break;
400                         }
401                         i++;
402                 }
403         }
404
405         return vertMap;
406 }
407
408 BM_INLINE void bmesh_quick_edgedraw_flag(MEdge *med, BMEdge *e)
409 {
410         /* this is a cheap way to set the edge draw, its not precise and will
411          * pick the first 2 faces an edge uses */
412
413
414         if ( /* (med->flag & ME_EDGEDRAW) && */ /* assume to be true */
415              (e->l && (e->l != e->l->radial_next)) &&
416              (dot_v3v3(e->l->f->no, e->l->radial_next->f->no) > 0.998f))
417         {
418                 med->flag &= ~ME_EDGEDRAW;
419         }
420 }
421
422
423 void bmesh_to_mesh_exec(BMesh *bm, BMOperator *op)
424 {
425         Mesh *me = BMO_Get_Pnt(op, "mesh");
426         /* Object *ob = BMO_Get_Pnt(op, "object"); */
427         MLoop *mloop;
428         MPoly *mpoly;
429         MVert *mvert, *oldverts;
430         MEdge *med, *medge;
431         BMVert *v, *eve;
432         BMEdge *e;
433         BMLoop *l;
434         BMFace *f;
435         BMIter iter, liter;
436         int i, j, *keyi, ototvert, totloop;
437         int dotess = !BMO_Get_Int(op, "notesselation");
438         
439         ototvert = me->totvert;
440
441         /* new Vertex block */
442         if (bm->totvert==0) mvert= NULL;
443         else mvert= MEM_callocN(bm->totvert*sizeof(MVert), "loadeditbMesh vert");
444
445         /* new Edge block */
446         if (bm->totedge==0) medge= NULL;
447         else medge= MEM_callocN(bm->totedge*sizeof(MEdge), "loadeditbMesh edge");
448         
449         /*build ngon data*/
450         /* new Ngon Face block */
451         if (bm->totface==0) mpoly = NULL;
452         else mpoly= MEM_callocN(bm->totface*sizeof(MPoly), "loadeditbMesh poly");
453         
454         /*find number of loops to allocate*/
455         totloop = 0;
456         BM_ITER(f, &iter, bm, BM_FACES_OF_MESH, NULL) {
457                 totloop += f->len;
458         }
459
460         if (totloop==0) mloop = NULL;
461         else mloop = MEM_callocN(totloop*sizeof(MLoop), "loadeditbMesh loop");
462
463         /* lets save the old verts just in case we are actually working on
464          * a key ... we now do processing of the keys at the end */
465         oldverts= me->mvert;
466
467         /* don't free this yet */
468         CustomData_set_layer(&me->vdata, CD_MVERT, NULL);
469
470         /* free custom data */
471         CustomData_free(&me->vdata, me->totvert);
472         CustomData_free(&me->edata, me->totedge);
473         CustomData_free(&me->fdata, me->totface);
474         CustomData_free(&me->ldata, me->totloop);
475         CustomData_free(&me->pdata, me->totpoly);
476
477         /* add new custom data */
478         me->totvert= bm->totvert;
479         me->totedge= bm->totedge;
480         me->totloop= totloop;
481         me->totpoly= bm->totface;
482         /* will be overwritten with a valid value if 'dotess' is set, otherwise we
483          * end up with 'me->totface' and me->mface == NULL which can crash [#28625]
484          */
485         me->totface= 0;
486
487         CustomData_copy(&bm->vdata, &me->vdata, CD_MASK_MESH, CD_CALLOC, me->totvert);
488         CustomData_copy(&bm->edata, &me->edata, CD_MASK_MESH, CD_CALLOC, me->totedge);
489         CustomData_copy(&bm->ldata, &me->ldata, CD_MASK_MESH, CD_CALLOC, me->totloop);
490         CustomData_copy(&bm->pdata, &me->pdata, CD_MASK_MESH, CD_CALLOC, me->totpoly);
491
492         CustomData_add_layer(&me->vdata, CD_MVERT, CD_ASSIGN, mvert, me->totvert);
493         CustomData_add_layer(&me->edata, CD_MEDGE, CD_ASSIGN, medge, me->totedge);
494         CustomData_add_layer(&me->ldata, CD_MLOOP, CD_ASSIGN, mloop, me->totloop);
495         CustomData_add_layer(&me->pdata, CD_MPOLY, CD_ASSIGN, mpoly, me->totpoly);
496
497         /* this is called again, 'dotess' arg is used there */
498         mesh_update_customdata_pointers(me, 0);
499         
500         i = 0;
501         BM_ITER(v, &iter, bm, BM_VERTS_OF_MESH, NULL) {
502                 float *bweight = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_BWEIGHT);
503
504                 mvert->bweight = bweight ? (char)((*bweight)*255) : 0;
505
506                 copy_v3_v3(mvert->co, v->co);
507                 normal_float_to_short_v3(mvert->no, v->no);
508                 
509                 mvert->flag = BM_Vert_Flag_To_MEFlag(v);
510
511                 BM_SetIndex(v, i); /* set_inline */
512
513                 /*copy over customdata*/
514                 CustomData_from_bmesh_block(&bm->vdata, &me->vdata, v->head.data, i);
515
516                 i++;
517                 mvert++;
518
519                 BM_CHECK_ELEMENT(bm, v);
520         }
521         bm->elem_index_dirty &= ~BM_VERT;
522
523         med= medge;
524         i = 0;
525         BM_ITER(e, &iter, bm, BM_EDGES_OF_MESH, NULL) {
526                 float *crease = CustomData_bmesh_get(&bm->edata, e->head.data, CD_CREASE);
527                 float *bweight = CustomData_bmesh_get(&bm->edata, e->head.data, CD_BWEIGHT);
528                 
529                 med->v1 = BM_GetIndex(e->v1);
530                 med->v2 = BM_GetIndex(e->v2);
531                 med->crease = crease ? (char)((*crease)*255) : 0;
532                 med->bweight = bweight ? (char)((*bweight)*255) : 0;
533                 
534                 med->flag = BM_Edge_Flag_To_MEFlag(e);
535                 
536                 BM_SetIndex(e, i); /* set_inline */
537
538                 /*copy over customdata*/
539                 CustomData_from_bmesh_block(&bm->edata, &me->edata, e->head.data, i);
540
541                 bmesh_quick_edgedraw_flag(med, e);
542
543                 i++;
544                 med++;
545                 BM_CHECK_ELEMENT(bm, e);
546         }
547         bm->elem_index_dirty &= ~BM_EDGE;
548
549         i = 0;
550         j = 0;
551         BM_ITER(f, &iter, bm, BM_FACES_OF_MESH, NULL) {
552                 mpoly->loopstart = j;
553                 mpoly->totloop = f->len;
554                 mpoly->mat_nr = f->mat_nr;
555                 mpoly->flag = BM_Face_Flag_To_MEFlag(f);
556
557                 l = BMIter_New(&liter, bm, BM_LOOPS_OF_FACE, f);
558                 for ( ; l; l=BMIter_Step(&liter), j++, mloop++) {
559                         mloop->e = BM_GetIndex(l->e);
560                         mloop->v = BM_GetIndex(l->v);
561
562                         /*copy over customdata*/
563                         CustomData_from_bmesh_block(&bm->ldata, &me->ldata, l->head.data, j);
564                         BM_CHECK_ELEMENT(bm, l);
565                         BM_CHECK_ELEMENT(bm, l->e);
566                         BM_CHECK_ELEMENT(bm, l->v);
567                 }
568                 
569                 if (f == bm->act_face) me->act_face = i;
570
571                 /*copy over customdata*/
572                 CustomData_from_bmesh_block(&bm->pdata, &me->pdata, f->head.data, i);
573
574                 i++;
575                 mpoly++;
576                 BM_CHECK_ELEMENT(bm, f);
577         }
578
579         /* patch hook indices and vertex parents */
580         if (ototvert > 0) {
581                 Object *ob;
582                 ModifierData *md;
583                 BMVert **vertMap = NULL;
584                 int i,j;
585
586                 for (ob=G.main->object.first; ob; ob=ob->id.next) {
587                         if (ob->parent==bm->ob && ELEM(ob->partype, PARVERT1,PARVERT3)) {
588
589                                 if (vertMap == NULL) {
590                                         vertMap= bmesh_to_mesh_vertex_map(bm, ototvert);
591                                 }
592
593                                 if (ob->par1 < ototvert) {
594                                         eve = vertMap[ob->par1];
595                                         if (eve) ob->par1= BM_GetIndex(eve);
596                                 }
597                                 if (ob->par2 < ototvert) {
598                                         eve = vertMap[ob->par2];
599                                         if (eve) ob->par2= BM_GetIndex(eve);
600                                 }
601                                 if (ob->par3 < ototvert) {
602                                         eve = vertMap[ob->par3];
603                                         if (eve) ob->par3= BM_GetIndex(eve);
604                                 }
605                                 
606                         }
607                         if (ob->data==me) {
608                                 for (md=ob->modifiers.first; md; md=md->next) {
609                                         if (md->type==eModifierType_Hook) {
610                                                 HookModifierData *hmd = (HookModifierData*) md;
611
612                                                 if (vertMap == NULL) {
613                                                         vertMap= bmesh_to_mesh_vertex_map(bm, ototvert);
614                                                 }
615                                                 
616                                                 for (i=j=0; i<hmd->totindex; i++) {
617                                                         if (hmd->indexar[i] < ototvert) {
618                                                                 eve = vertMap[hmd->indexar[i]];
619                                                                 
620                                                                 if (eve) {
621                                                                         hmd->indexar[j++] = BM_GetIndex(eve);
622                                                                 }
623                                                         }
624                                                         else j++;
625                                                 }
626
627                                                 hmd->totindex = j;
628                                         }
629                                 }
630                         }
631                 }
632
633                 if (vertMap) MEM_freeN(vertMap);
634         }
635
636         if (dotess) {
637                 BKE_mesh_calc_tessface(me);
638         }
639
640         mesh_update_customdata_pointers(me, dotess);
641
642         {
643                 BMEditSelection *selected;
644                 me->totselect = BLI_countlist(&(bm->selected));
645
646                 if (me->mselect) MEM_freeN(me->mselect);
647
648                 me->mselect = MEM_callocN(sizeof(MSelect) * me->totselect, "Mesh selection history");
649
650
651                 for (i = 0, selected = bm->selected.first; selected; i++, selected = selected->next) {
652                         if (selected->htype == BM_VERT) {
653                                 me->mselect[i].type = ME_VSEL;
654
655                         }
656                         else if (selected->htype == BM_EDGE) {
657                                 me->mselect[i].type = ME_ESEL;
658
659                         }
660                         else if (selected->htype == BM_FACE) {
661                                 me->mselect[i].type = ME_FSEL;
662                         }
663
664                         me->mselect[i].index = BM_GetIndex(selected->data);
665                 }
666         }
667
668         /* see comment below, this logic is in twice */
669
670         if (me->key) {
671                 KeyBlock *currkey;
672                 KeyBlock *actkey= BLI_findlink(&me->key->block, bm->shapenr-1);
673
674                 float (*ofs)[3] = NULL;
675
676                 /*go through and find any shapekey customdata layers
677                   that might not have corrusponding KeyBlocks, and add them if
678                   necassary.*/
679                 j = 0;
680                 for (i=0; i<bm->vdata.totlayer; i++) {
681                         if (bm->vdata.layers[i].type != CD_SHAPEKEY)
682                                 continue;
683
684                         for (currkey=me->key->block.first; currkey; currkey=currkey->next) {
685                                 if (currkey->uid == bm->vdata.layers[i].uid)
686                                         break;
687                         }
688                         
689                         if (!currkey) {
690                                 currkey = MEM_callocN(sizeof(KeyBlock), "KeyBlock mesh_conv.c");
691                                 currkey->type = KEY_LINEAR;
692                                 currkey->slidermin = 0.0f;
693                                 currkey->slidermax = 1.0f;
694
695                                 BLI_addtail(&me->key->block, currkey);
696                                 me->key->totkey++;
697                         }
698
699                         j++;
700                 }
701
702
703                 /* editing the base key should update others */
704                 if (me->key->type==KEY_RELATIVE && oldverts) {
705                         int act_is_basis = 0;
706                         /* find if this key is a basis for any others */
707                         for (currkey = me->key->block.first; currkey; currkey= currkey->next) {
708                                 if (bm->shapenr-1 == currkey->relative) {
709                                         act_is_basis = 1;
710                                         break;
711                                 }
712                         }
713
714                         if (act_is_basis) { /* active key is a base */
715                                 float (*fp)[3]= actkey->data;
716                                 int *keyi;
717                                 i=0;
718                                 ofs= MEM_callocN(sizeof(float) * 3 * bm->totvert,  "currkey->data");
719                                 mvert = me->mvert;
720                                 BM_ITER(eve, &iter, bm, BM_VERTS_OF_MESH, NULL) {
721                                         keyi = CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_SHAPE_KEYINDEX);
722                                         if (keyi && *keyi != ORIGINDEX_NONE) {
723                                                 sub_v3_v3v3(ofs[i], mvert->co, fp[*keyi]);
724                                         }
725                                         i++;
726                                         mvert++;
727                                 }
728                         }
729                 }
730
731
732                 for (currkey=me->key->block.first; currkey; currkey=currkey->next) {
733                         j = 0;
734
735                         for (i=0; i<bm->vdata.totlayer; i++) {
736                                 if (bm->vdata.layers[i].type != CD_SHAPEKEY)
737                                         continue;
738
739                                 if (currkey->uid == bm->vdata.layers[i].uid) {
740                                         int apply_offset = (ofs && (currkey != actkey) && (bm->shapenr-1 == currkey->relative));
741                                         float *fp, *co;
742                                         float (*ofs_pt)[3] = ofs;
743
744                                         if (currkey->data)
745                                                 MEM_freeN(currkey->data);
746                                         currkey->data = fp = MEM_mallocN(sizeof(float)*3*bm->totvert, "shape key data");
747                                         currkey->totelem = bm->totvert;
748
749                                         BM_ITER(eve, &iter, bm, BM_VERTS_OF_MESH, NULL) {
750                                                 co = currkey==actkey ? eve->co : CustomData_bmesh_get_n(&bm->vdata, eve->head.data, CD_SHAPEKEY, j);
751                                                 
752                                                 copy_v3_v3(fp, co);
753
754                                                 /* propagate edited basis offsets to other shapes */
755                                                 if (apply_offset) {
756                                                         add_v3_v3(fp, *ofs_pt++);
757                                                 }
758
759                                                 fp += 3;
760                                         }
761                                         break;
762                                 }
763
764                                 j++;
765                         }
766
767                         /*if we didn't find a shapekey, tag the block to be reconstructed
768                           via the old method below*/
769                         if (j == CustomData_number_of_layers(&bm->vdata, CD_SHAPEKEY)) {
770                                 currkey->flag |= KEYBLOCK_MISSING;
771                         }
772                 }
773
774                 if (ofs) MEM_freeN(ofs);
775         }
776
777         /* XXX, code below is from trunk and a duplicate functionality
778          * to the block above.
779          * We should use one or the other, having both means we have to maintain
780          * both and keep them working the same way which is a hassle - campbell */
781
782         /* old method of reconstructing keys via vertice's original key indices,
783            currently used if the new method above fails (which is theoretically
784            possible in certain cases of undo).*/
785         if (me->key) {
786                 float *fp, *newkey, *oldkey;
787                 KeyBlock *currkey;
788                 KeyBlock *actkey= BLI_findlink(&me->key->block, bm->shapenr-1);
789
790                 float (*ofs)[3] = NULL;
791
792                 /* editing the base key should update others */
793                 if (me->key->type==KEY_RELATIVE && oldverts) {
794                         int act_is_basis = 0;
795                         /* find if this key is a basis for any others */
796                         for (currkey = me->key->block.first; currkey; currkey= currkey->next) {
797                                 if (bm->shapenr-1 == currkey->relative) {
798                                         act_is_basis = 1;
799                                         break;
800                                 }
801                         }
802
803                         if (act_is_basis) { /* active key is a base */
804                                 float (*fp)[3]= actkey->data;
805                                 int *keyi;
806                                 i=0;
807                                 ofs= MEM_callocN(sizeof(float) * 3 * bm->totvert,  "currkey->data");
808                                 mvert = me->mvert;
809                                 BM_ITER(eve, &iter, bm, BM_VERTS_OF_MESH, NULL) {
810                                         keyi = CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_SHAPE_KEYINDEX);
811                                         if (keyi && *keyi != ORIGINDEX_NONE) {
812                                                 sub_v3_v3v3(ofs[i], mvert->co, fp[*keyi]);
813                                         }
814                                         i++;
815                                         mvert++;
816                                 }
817                         }
818                 }
819
820                 /* Lets reorder the key data so that things line up roughly
821                  * with the way things were before editmode */
822                 currkey = me->key->block.first;
823                 while (currkey) {
824                         int apply_offset = (ofs && (currkey != actkey) && (bm->shapenr-1 == currkey->relative));
825
826                         if (!(currkey->flag & KEYBLOCK_MISSING)) {
827                                 currkey = currkey->next;
828                                 continue;
829                         }
830                         
831                         printf("warning: had to hackishly reconstruct shape key \"%s\","
832                                " it may not be correct anymore.\n", currkey->name);
833
834                         currkey->flag &= ~KEYBLOCK_MISSING;
835
836                         fp= newkey= MEM_callocN(me->key->elemsize*bm->totvert,  "currkey->data");
837                         oldkey = currkey->data;
838
839                         eve= BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
840
841                         i = 0;
842                         mvert = me->mvert;
843                         while (eve) {
844                                 keyi = CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_SHAPE_KEYINDEX);
845                                 if (!keyi) {
846                                         break;
847                                 }
848                                 if (*keyi >= 0 && *keyi < currkey->totelem) { // valid old vertex
849                                         if (currkey == actkey) {
850                                                 if (actkey == me->key->refkey) {
851                                                         copy_v3_v3(fp, mvert->co);
852                                                 }
853                                                 else {
854                                                         copy_v3_v3(fp, mvert->co);
855                                                         if (oldverts) {
856                                                                 copy_v3_v3(mvert->co, oldverts[*keyi].co);
857                                                         }
858                                                 }
859                                         }
860                                         else {
861                                                 if (oldkey) {
862                                                         copy_v3_v3(fp, oldkey + 3 * *keyi);
863                                                 }
864                                         }
865                                 }
866                                 else {
867                                         copy_v3_v3(fp, mvert->co);
868                                 }
869
870                                 /* propagate edited basis offsets to other shapes */
871                                 if (apply_offset) {
872                                         add_v3_v3(fp, ofs[i]);
873                                 }
874
875                                 fp+= 3;
876                                 ++i;
877                                 ++mvert;
878                                 eve= BMIter_Step(&iter);
879                         }
880                         currkey->totelem= bm->totvert;
881                         if (currkey->data) MEM_freeN(currkey->data);
882                         currkey->data = newkey;
883                         
884                         currkey= currkey->next;
885                 }
886
887                 if (ofs) MEM_freeN(ofs);
888         }
889
890         if (oldverts) MEM_freeN(oldverts);
891 }