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