Cleanup: style, use braces for editors
[blender.git] / source / blender / editors / mesh / meshtools.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2004 by Blender Foundation
17  * All rights reserved.
18  */
19
20 /** \file
21  * \ingroup edmesh
22  *
23  * meshtools.c: no editmode (violated already :), mirror & join),
24  * tools operating on meshes
25  */
26
27 #include "MEM_guardedalloc.h"
28
29 #include "DNA_key_types.h"
30 #include "DNA_material_types.h"
31 #include "DNA_mesh_types.h"
32 #include "DNA_meshdata_types.h"
33 #include "DNA_modifier_types.h"
34 #include "DNA_object_types.h"
35 #include "DNA_scene_types.h"
36 #include "DNA_screen_types.h"
37 #include "DNA_view3d_types.h"
38 #include "DNA_workspace_types.h"
39
40 #include "BLI_math.h"
41 #include "BLI_blenlib.h"
42
43 #include "BKE_context.h"
44 #include "BKE_deform.h"
45 #include "BKE_editmesh.h"
46 #include "BKE_key.h"
47 #include "BKE_layer.h"
48 #include "BKE_library.h"
49 #include "BKE_main.h"
50 #include "BKE_material.h"
51 #include "BKE_mesh.h"
52 #include "BKE_mesh_iterators.h"
53 #include "BKE_mesh_runtime.h"
54 #include "BKE_multires.h"
55 #include "BKE_object.h"
56 #include "BKE_object_deform.h"
57 #include "BKE_report.h"
58
59 #include "DEG_depsgraph.h"
60 #include "DEG_depsgraph_build.h"
61 #include "DEG_depsgraph_query.h"
62
63 #include "ED_mesh.h"
64 #include "ED_object.h"
65 #include "ED_view3d.h"
66
67 #include "WM_api.h"
68 #include "WM_types.h"
69
70 /* * ********************** no editmode!!! *********** */
71
72 /*********************** JOIN ***************************/
73
74 /* join selected meshes into the active mesh, context sensitive
75  * return 0 if no join is made (error) and 1 if the join is done */
76
77 static void join_mesh_single(Depsgraph *depsgraph,
78                              Main *bmain,
79                              Scene *scene,
80                              Object *ob_dst,
81                              Object *ob_src,
82                              float imat[4][4],
83                              MVert **mvert_pp,
84                              MEdge **medge_pp,
85                              MLoop **mloop_pp,
86                              MPoly **mpoly_pp,
87                              CustomData *vdata,
88                              CustomData *edata,
89                              CustomData *ldata,
90                              CustomData *pdata,
91                              int totvert,
92                              int totedge,
93                              int totloop,
94                              int totpoly,
95                              Key *key,
96                              Key *nkey,
97                              Material **matar,
98                              int *matmap,
99                              int totcol,
100                              int *vertofs,
101                              int *edgeofs,
102                              int *loopofs,
103                              int *polyofs)
104 {
105   int a, b;
106
107   Mesh *me = ob_src->data;
108   MVert *mvert = *mvert_pp;
109   MEdge *medge = *medge_pp;
110   MLoop *mloop = *mloop_pp;
111   MPoly *mpoly = *mpoly_pp;
112
113   if (me->totvert) {
114     /* merge customdata flag */
115     ((Mesh *)ob_dst->data)->cd_flag |= me->cd_flag;
116
117     /* standard data */
118     CustomData_merge(&me->vdata, vdata, CD_MASK_MESH.vmask, CD_DEFAULT, totvert);
119     CustomData_copy_data_named(&me->vdata, vdata, 0, *vertofs, me->totvert);
120
121     /* vertex groups */
122     MDeformVert *dvert = CustomData_get(vdata, *vertofs, CD_MDEFORMVERT);
123     MDeformVert *dvert_src = CustomData_get(&me->vdata, 0, CD_MDEFORMVERT);
124
125     /* Remap to correct new vgroup indices, if needed. */
126     if (dvert_src) {
127       BLI_assert(dvert != NULL);
128
129       /* Build src to merged mapping of vgroup indices. */
130       int *vgroup_index_map;
131       int vgroup_index_map_len;
132       vgroup_index_map = BKE_object_defgroup_index_map_create(
133           ob_src, ob_dst, &vgroup_index_map_len);
134       BKE_object_defgroup_index_map_apply(
135           dvert, me->totvert, vgroup_index_map, vgroup_index_map_len);
136       if (vgroup_index_map != NULL) {
137         MEM_freeN(vgroup_index_map);
138       }
139     }
140
141     /* if this is the object we're merging into, no need to do anything */
142     if (ob_src != ob_dst) {
143       float cmat[4][4];
144
145       /* watch this: switch matmul order really goes wrong */
146       mul_m4_m4m4(cmat, imat, ob_src->obmat);
147
148       /* transform vertex coordinates into new space */
149       for (a = 0, mvert = *mvert_pp; a < me->totvert; a++, mvert++) {
150         mul_m4_v3(cmat, mvert->co);
151       }
152
153       /* For each shapekey in destination mesh:
154        * - if there's a matching one, copy it across
155        *   (will need to transform vertices into new space...).
156        * - otherwise, just copy own coordinates of mesh
157        *   (no need to transform vertex coordinates into new space).
158        */
159       if (key) {
160         /* if this mesh has any shapekeys, check first, otherwise just copy coordinates */
161         for (KeyBlock *kb = key->block.first; kb; kb = kb->next) {
162           /* get pointer to where to write data for this mesh in shapekey's data array */
163           float(*cos)[3] = ((float(*)[3])kb->data) + *vertofs;
164
165           /* check if this mesh has such a shapekey */
166           KeyBlock *okb = me->key ? BKE_keyblock_find_name(me->key, kb->name) : NULL;
167           if (okb) {
168             /* copy this mesh's shapekey to the destination shapekey
169              * (need to transform first) */
170             float(*ocos)[3] = okb->data;
171             for (a = 0; a < me->totvert; a++, cos++, ocos++) {
172               copy_v3_v3(*cos, *ocos);
173               mul_m4_v3(cmat, *cos);
174             }
175           }
176           else {
177             /* copy this mesh's vertex coordinates to the destination shapekey */
178             for (a = 0, mvert = *mvert_pp; a < me->totvert; a++, cos++, mvert++) {
179               copy_v3_v3(*cos, mvert->co);
180             }
181           }
182         }
183       }
184     }
185     else {
186       /* for each shapekey in destination mesh:
187        * - if it was an 'original', copy the appropriate data from nkey
188        * - otherwise, copy across plain coordinates (no need to transform coordinates)
189        */
190       if (key) {
191         for (KeyBlock *kb = key->block.first; kb; kb = kb->next) {
192           /* get pointer to where to write data for this mesh in shapekey's data array */
193           float(*cos)[3] = ((float(*)[3])kb->data) + *vertofs;
194
195           /* check if this was one of the original shapekeys */
196           KeyBlock *okb = nkey ? BKE_keyblock_find_name(nkey, kb->name) : NULL;
197           if (okb) {
198             /* copy this mesh's shapekey to the destination shapekey */
199             float(*ocos)[3] = okb->data;
200             for (a = 0; a < me->totvert; a++, cos++, ocos++) {
201               copy_v3_v3(*cos, *ocos);
202             }
203           }
204           else {
205             /* copy base-coordinates to the destination shapekey */
206             for (a = 0, mvert = *mvert_pp; a < me->totvert; a++, cos++, mvert++) {
207               copy_v3_v3(*cos, mvert->co);
208             }
209           }
210         }
211       }
212     }
213   }
214
215   if (me->totedge) {
216     CustomData_merge(&me->edata, edata, CD_MASK_MESH.emask, CD_DEFAULT, totedge);
217     CustomData_copy_data_named(&me->edata, edata, 0, *edgeofs, me->totedge);
218
219     for (a = 0; a < me->totedge; a++, medge++) {
220       medge->v1 += *vertofs;
221       medge->v2 += *vertofs;
222     }
223   }
224
225   if (me->totloop) {
226     if (ob_src != ob_dst) {
227       MultiresModifierData *mmd;
228
229       multiresModifier_prepare_join(depsgraph, scene, ob_src, ob_dst);
230
231       if ((mmd = get_multires_modifier(scene, ob_src, true))) {
232         ED_object_iter_other(
233             bmain, ob_src, true, ED_object_multires_update_totlevels_cb, &mmd->totlvl);
234       }
235     }
236
237     CustomData_merge(&me->ldata, ldata, CD_MASK_MESH.lmask, CD_DEFAULT, totloop);
238     CustomData_copy_data_named(&me->ldata, ldata, 0, *loopofs, me->totloop);
239
240     for (a = 0; a < me->totloop; a++, mloop++) {
241       mloop->v += *vertofs;
242       mloop->e += *edgeofs;
243     }
244   }
245
246   if (me->totpoly) {
247     if (matmap) {
248       /* make mapping for materials */
249       for (a = 1; a <= ob_src->totcol; a++) {
250         Material *ma = give_current_material(ob_src, a);
251
252         for (b = 0; b < totcol; b++) {
253           if (ma == matar[b]) {
254             matmap[a - 1] = b;
255             break;
256           }
257         }
258       }
259     }
260
261     CustomData_merge(&me->pdata, pdata, CD_MASK_MESH.pmask, CD_DEFAULT, totpoly);
262     CustomData_copy_data_named(&me->pdata, pdata, 0, *polyofs, me->totpoly);
263
264     for (a = 0; a < me->totpoly; a++, mpoly++) {
265       mpoly->loopstart += *loopofs;
266       mpoly->mat_nr = matmap ? matmap[mpoly->mat_nr] : 0;
267     }
268   }
269
270   /* these are used for relinking (cannot be set earlier, or else reattaching goes wrong) */
271   *vertofs += me->totvert;
272   *mvert_pp += me->totvert;
273   *edgeofs += me->totedge;
274   *medge_pp += me->totedge;
275   *loopofs += me->totloop;
276   *mloop_pp += me->totloop;
277   *polyofs += me->totpoly;
278   *mpoly_pp += me->totpoly;
279 }
280
281 int join_mesh_exec(bContext *C, wmOperator *op)
282 {
283   Main *bmain = CTX_data_main(C);
284   Scene *scene = CTX_data_scene(C);
285   Object *ob = CTX_data_active_object(C);
286   Material **matar = NULL, *ma;
287   Mesh *me;
288   MVert *mvert = NULL;
289   MEdge *medge = NULL;
290   MPoly *mpoly = NULL;
291   MLoop *mloop = NULL;
292   Key *key, *nkey = NULL;
293   KeyBlock *kb, *kbn;
294   float imat[4][4];
295   int a, b, totcol, totmat = 0, totedge = 0, totvert = 0;
296   int totloop = 0, totpoly = 0, vertofs, *matmap = NULL;
297   int i, haskey = 0, edgeofs, loopofs, polyofs;
298   bool ok = false;
299   bDeformGroup *dg, *odg;
300   CustomData vdata, edata, fdata, ldata, pdata;
301
302   if (ob->mode & OB_MODE_EDIT) {
303     BKE_report(op->reports, RPT_WARNING, "Cannot join while in edit mode");
304     return OPERATOR_CANCELLED;
305   }
306
307   /* ob is the object we are adding geometry to */
308   if (!ob || ob->type != OB_MESH) {
309     BKE_report(op->reports, RPT_WARNING, "Active object is not a mesh");
310     return OPERATOR_CANCELLED;
311   }
312
313   Depsgraph *depsgraph = CTX_data_depsgraph(C);
314
315   /* count & check */
316   CTX_DATA_BEGIN (C, Object *, ob_iter, selected_editable_objects) {
317     if (ob_iter->type == OB_MESH) {
318       me = ob_iter->data;
319
320       totvert += me->totvert;
321       totedge += me->totedge;
322       totloop += me->totloop;
323       totpoly += me->totpoly;
324       totmat += ob_iter->totcol;
325
326       if (ob_iter == ob) {
327         ok = true;
328       }
329
330       /* check for shapekeys */
331       if (me->key) {
332         haskey++;
333       }
334     }
335   }
336   CTX_DATA_END;
337
338   /* that way the active object is always selected */
339   if (ok == false) {
340     BKE_report(op->reports, RPT_WARNING, "Active object is not a selected mesh");
341     return OPERATOR_CANCELLED;
342   }
343
344   /* Only join meshes if there are verts to join,
345    * there aren't too many, and we only had one mesh selected. */
346   me = (Mesh *)ob->data;
347   key = me->key;
348
349   if (totvert == 0 || totvert == me->totvert) {
350     BKE_report(op->reports, RPT_WARNING, "No mesh data to join");
351     return OPERATOR_CANCELLED;
352   }
353
354   if (totvert > MESH_MAX_VERTS) {
355     BKE_reportf(op->reports,
356                 RPT_WARNING,
357                 "Joining results in %d vertices, limit is %ld",
358                 totvert,
359                 MESH_MAX_VERTS);
360     return OPERATOR_CANCELLED;
361   }
362
363   /* remove tessface to ensure we don't hold references to invalid faces */
364   BKE_mesh_tessface_clear(me);
365
366   /* new material indices and material array */
367   if (totmat) {
368     matar = MEM_callocN(sizeof(*matar) * totmat, "join_mesh matar");
369     matmap = MEM_callocN(sizeof(*matmap) * totmat, "join_mesh matmap");
370   }
371   totcol = ob->totcol;
372
373   /* obact materials in new main array, is nicer start! */
374   for (a = 0; a < ob->totcol; a++) {
375     matar[a] = give_current_material(ob, a + 1);
376     id_us_plus((ID *)matar[a]);
377     /* increase id->us : will be lowered later */
378   }
379
380   /* - if destination mesh had shapekeys, move them somewhere safe, and set up placeholders
381    *   with arrays that are large enough to hold shapekey data for all meshes
382    * - if destination mesh didn't have shapekeys, but we encountered some in the meshes we're
383    *   joining, set up a new keyblock and assign to the mesh
384    */
385   if (key) {
386     /* make a duplicate copy that will only be used here... (must remember to free it!) */
387     nkey = BKE_key_copy(bmain, key);
388
389     /* for all keys in old block, clear data-arrays */
390     for (kb = key->block.first; kb; kb = kb->next) {
391       if (kb->data) {
392         MEM_freeN(kb->data);
393       }
394       kb->data = MEM_callocN(sizeof(float) * 3 * totvert, "join_shapekey");
395       kb->totelem = totvert;
396     }
397   }
398   else if (haskey) {
399     /* add a new key-block and add to the mesh */
400     key = me->key = BKE_key_add(bmain, (ID *)me);
401     key->type = KEY_RELATIVE;
402   }
403
404   /* first pass over objects - copying materials and vertexgroups across */
405   CTX_DATA_BEGIN (C, Object *, ob_iter, selected_editable_objects) {
406     /* only act if a mesh, and not the one we're joining to */
407     if ((ob != ob_iter) && (ob_iter->type == OB_MESH)) {
408       me = ob_iter->data;
409
410       /* Join this object's vertex groups to the base one's */
411       for (dg = ob_iter->defbase.first; dg; dg = dg->next) {
412         /* See if this group exists in the object (if it doesn't, add it to the end) */
413         if (!defgroup_find_name(ob, dg->name)) {
414           odg = MEM_callocN(sizeof(bDeformGroup), "join deformGroup");
415           memcpy(odg, dg, sizeof(bDeformGroup));
416           BLI_addtail(&ob->defbase, odg);
417         }
418       }
419       if (ob->defbase.first && ob->actdef == 0) {
420         ob->actdef = 1;
421       }
422
423       if (me->totvert) {
424         /* Add this object's materials to the base one's if they don't exist already
425          * (but only if limits not exceeded yet) */
426         if (totcol < MAXMAT) {
427           for (a = 1; a <= ob_iter->totcol; a++) {
428             ma = give_current_material(ob_iter, a);
429
430             for (b = 0; b < totcol; b++) {
431               if (ma == matar[b]) {
432                 break;
433               }
434             }
435             if (b == totcol) {
436               matar[b] = ma;
437               if (ma) {
438                 id_us_plus(&ma->id);
439               }
440               totcol++;
441             }
442             if (totcol >= MAXMAT) {
443               break;
444             }
445           }
446         }
447
448         /* if this mesh has shapekeys,
449          * check if destination mesh already has matching entries too */
450         if (me->key && key) {
451           /* for remapping KeyBlock.relative */
452           int *index_map = MEM_mallocN(sizeof(int) * me->key->totkey, __func__);
453           KeyBlock **kb_map = MEM_mallocN(sizeof(KeyBlock *) * me->key->totkey, __func__);
454
455           for (kb = me->key->block.first, i = 0; kb; kb = kb->next, i++) {
456             BLI_assert(i < me->key->totkey);
457
458             kbn = BKE_keyblock_find_name(key, kb->name);
459             /* if key doesn't exist in destination mesh, add it */
460             if (kbn) {
461               index_map[i] = BLI_findindex(&key->block, kbn);
462             }
463             else {
464               index_map[i] = key->totkey;
465
466               kbn = BKE_keyblock_add(key, kb->name);
467
468               BKE_keyblock_copy_settings(kbn, kb);
469
470               /* adjust settings to fit (allocate a new data-array) */
471               kbn->data = MEM_callocN(sizeof(float) * 3 * totvert, "joined_shapekey");
472               kbn->totelem = totvert;
473             }
474
475             kb_map[i] = kbn;
476           }
477
478           /* remap relative index values */
479           for (kb = me->key->block.first, i = 0; kb; kb = kb->next, i++) {
480             /* sanity check, should always be true */
481             if (LIKELY(kb->relative < me->key->totkey)) {
482               kb_map[i]->relative = index_map[kb->relative];
483             }
484           }
485
486           MEM_freeN(index_map);
487           MEM_freeN(kb_map);
488         }
489       }
490     }
491   }
492   CTX_DATA_END;
493
494   /* setup new data for destination mesh */
495   CustomData_reset(&vdata);
496   CustomData_reset(&edata);
497   CustomData_reset(&fdata);
498   CustomData_reset(&ldata);
499   CustomData_reset(&pdata);
500
501   mvert = CustomData_add_layer(&vdata, CD_MVERT, CD_CALLOC, NULL, totvert);
502   medge = CustomData_add_layer(&edata, CD_MEDGE, CD_CALLOC, NULL, totedge);
503   mloop = CustomData_add_layer(&ldata, CD_MLOOP, CD_CALLOC, NULL, totloop);
504   mpoly = CustomData_add_layer(&pdata, CD_MPOLY, CD_CALLOC, NULL, totpoly);
505
506   vertofs = 0;
507   edgeofs = 0;
508   loopofs = 0;
509   polyofs = 0;
510
511   /* inverse transform for all selected meshes in this object */
512   invert_m4_m4(imat, ob->obmat);
513
514   /* Add back active mesh first.
515    * This allows to keep things similar as they were, as much as possible
516    * (i.e. data from active mesh will remain first ones in new result of the merge,
517    * in same order for CD layers, etc). See also T50084.
518    */
519   join_mesh_single(depsgraph,
520                    bmain,
521                    scene,
522                    ob,
523                    ob,
524                    imat,
525                    &mvert,
526                    &medge,
527                    &mloop,
528                    &mpoly,
529                    &vdata,
530                    &edata,
531                    &ldata,
532                    &pdata,
533                    totvert,
534                    totedge,
535                    totloop,
536                    totpoly,
537                    key,
538                    nkey,
539                    matar,
540                    matmap,
541                    totcol,
542                    &vertofs,
543                    &edgeofs,
544                    &loopofs,
545                    &polyofs);
546
547   CTX_DATA_BEGIN (C, Object *, ob_iter, selected_editable_objects) {
548     if (ob_iter == ob) {
549       continue;
550     }
551     /* only join if this is a mesh */
552     if (ob_iter->type == OB_MESH) {
553       join_mesh_single(depsgraph,
554                        bmain,
555                        scene,
556                        ob,
557                        ob_iter,
558                        imat,
559                        &mvert,
560                        &medge,
561                        &mloop,
562                        &mpoly,
563                        &vdata,
564                        &edata,
565                        &ldata,
566                        &pdata,
567                        totvert,
568                        totedge,
569                        totloop,
570                        totpoly,
571                        key,
572                        nkey,
573                        matar,
574                        matmap,
575                        totcol,
576                        &vertofs,
577                        &edgeofs,
578                        &loopofs,
579                        &polyofs);
580
581       /* free base, now that data is merged */
582       if (ob_iter != ob) {
583         ED_object_base_free_and_unlink(bmain, scene, ob_iter);
584       }
585     }
586   }
587   CTX_DATA_END;
588
589   /* return to mesh we're merging to */
590   me = ob->data;
591
592   CustomData_free(&me->vdata, me->totvert);
593   CustomData_free(&me->edata, me->totedge);
594   CustomData_free(&me->ldata, me->totloop);
595   CustomData_free(&me->pdata, me->totpoly);
596
597   me->totvert = totvert;
598   me->totedge = totedge;
599   me->totloop = totloop;
600   me->totpoly = totpoly;
601
602   me->vdata = vdata;
603   me->edata = edata;
604   me->ldata = ldata;
605   me->pdata = pdata;
606
607   /* tessface data removed above, no need to update */
608   BKE_mesh_update_customdata_pointers(me, false);
609
610   /* update normals in case objects with non-uniform scale are joined */
611   BKE_mesh_calc_normals(me);
612
613   /* old material array */
614   for (a = 1; a <= ob->totcol; a++) {
615     ma = ob->mat[a - 1];
616     if (ma) {
617       id_us_min(&ma->id);
618     }
619   }
620   for (a = 1; a <= me->totcol; a++) {
621     ma = me->mat[a - 1];
622     if (ma) {
623       id_us_min(&ma->id);
624     }
625   }
626   MEM_SAFE_FREE(ob->mat);
627   MEM_SAFE_FREE(ob->matbits);
628   MEM_SAFE_FREE(me->mat);
629
630   if (totcol) {
631     me->mat = matar;
632     ob->mat = MEM_callocN(sizeof(*ob->mat) * totcol, "join obmatar");
633     ob->matbits = MEM_callocN(sizeof(*ob->matbits) * totcol, "join obmatbits");
634     MEM_freeN(matmap);
635   }
636
637   ob->totcol = me->totcol = totcol;
638
639   /* other mesh users */
640   test_all_objects_materials(bmain, (ID *)me);
641
642   /* free temp copy of destination shapekeys (if applicable) */
643   if (nkey) {
644     /* We can assume nobody is using that ID currently. */
645     BKE_id_free_ex(bmain, nkey, LIB_ID_FREE_NO_UI_USER, false);
646   }
647
648   /* ensure newly inserted keys are time sorted */
649   if (key && (key->type != KEY_RELATIVE)) {
650     BKE_key_sort(key);
651   }
652
653   /* Due to dependnecy cycle some other object might access old derived data. */
654   BKE_object_free_derived_caches(ob);
655
656   DEG_relations_tag_update(bmain); /* removed objects, need to rebuild dag */
657
658   DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
659
660   DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
661   WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
662
663   return OPERATOR_FINISHED;
664 }
665
666 /*********************** JOIN AS SHAPES ***************************/
667
668 /* Append selected meshes vertex locations as shapes of the active mesh,
669  * return 0 if no join is made (error) and 1 of the join is done */
670
671 int join_mesh_shapes_exec(bContext *C, wmOperator *op)
672 {
673   Main *bmain = CTX_data_main(C);
674   Scene *scene = CTX_data_scene(C);
675   Object *ob_active = CTX_data_active_object(C);
676   Depsgraph *depsgraph = CTX_data_depsgraph(C);
677   Mesh *me = (Mesh *)ob_active->data;
678   Mesh *selme = NULL;
679   Mesh *me_deformed = NULL;
680   Key *key = me->key;
681   KeyBlock *kb;
682   bool ok = false, nonequal_verts = false;
683
684   CTX_DATA_BEGIN (C, Object *, ob_iter, selected_editable_objects) {
685     if (ob_iter == ob_active) {
686       continue;
687     }
688
689     if (ob_iter->type == OB_MESH) {
690       selme = (Mesh *)ob_iter->data;
691
692       if (selme->totvert == me->totvert) {
693         ok = true;
694       }
695       else {
696         nonequal_verts = 1;
697       }
698     }
699   }
700   CTX_DATA_END;
701
702   if (!ok) {
703     if (nonequal_verts) {
704       BKE_report(op->reports, RPT_WARNING, "Selected meshes must have equal numbers of vertices");
705     }
706     else {
707       BKE_report(op->reports,
708                  RPT_WARNING,
709                  "No additional selected meshes with equal vertex count to join");
710     }
711     return OPERATOR_CANCELLED;
712   }
713
714   if (key == NULL) {
715     key = me->key = BKE_key_add(bmain, (ID *)me);
716     key->type = KEY_RELATIVE;
717
718     /* first key added, so it was the basis. initialize it with the existing mesh */
719     kb = BKE_keyblock_add(key, NULL);
720     BKE_keyblock_convert_from_mesh(me, key, kb);
721   }
722
723   /* now ready to add new keys from selected meshes */
724   CTX_DATA_BEGIN (C, Object *, ob_iter, selected_editable_objects) {
725     if (ob_iter == ob_active) {
726       continue;
727     }
728
729     if (ob_iter->type == OB_MESH) {
730       selme = (Mesh *)ob_iter->data;
731
732       if (selme->totvert == me->totvert) {
733         Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
734         Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob_iter);
735
736         me_deformed = mesh_get_eval_deform(depsgraph, scene_eval, ob_eval, &CD_MASK_BAREMESH);
737
738         if (!me_deformed) {
739           continue;
740         }
741
742         kb = BKE_keyblock_add(key, ob_iter->id.name + 2);
743
744         BKE_mesh_runtime_eval_to_meshkey(me_deformed, me, kb);
745       }
746     }
747   }
748   CTX_DATA_END;
749
750   DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
751   WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
752
753   return OPERATOR_FINISHED;
754 }
755
756 /* -------------------------------------------------------------------- */
757 /* Mesh Mirror (Topology) */
758
759 /** \name Mesh Topology Mirror API
760  * \{ */
761
762 static MirrTopoStore_t mesh_topo_store = {NULL, -1. - 1, -1};
763
764 /** mode is 's' start, or 'e' end, or 'u' use
765  * if end, ob can be NULL.
766  * \note, is supposed return -1 on error,
767  * which callers are currently checking for, but is not used so far. */
768 int ED_mesh_mirror_topo_table(Object *ob, Mesh *me_eval, char mode)
769 {
770   if (mode == 'u') { /* use table */
771     if (ED_mesh_mirrtopo_recalc_check(ob->data, me_eval, &mesh_topo_store)) {
772       ED_mesh_mirror_topo_table(ob, me_eval, 's');
773     }
774   }
775   else if (mode == 's') { /* start table */
776     ED_mesh_mirrtopo_init(ob->data, me_eval, &mesh_topo_store, false);
777   }
778   else if (mode == 'e') { /* end table */
779     ED_mesh_mirrtopo_free(&mesh_topo_store);
780   }
781   else {
782     BLI_assert(0);
783   }
784
785   return 0;
786 }
787
788 /** \} */
789
790 static int mesh_get_x_mirror_vert_spatial(Object *ob, Mesh *mesh, int index)
791 {
792   Mesh *me = ob->data;
793   MVert *mvert = mesh ? mesh->mvert : me->mvert;
794   float vec[3];
795
796   mvert = &mvert[index];
797   vec[0] = -mvert->co[0];
798   vec[1] = mvert->co[1];
799   vec[2] = mvert->co[2];
800
801   return ED_mesh_mirror_spatial_table(ob, NULL, mesh, vec, 'u');
802 }
803
804 static int mesh_get_x_mirror_vert_topo(Object *ob, Mesh *mesh, int index)
805 {
806   if (ED_mesh_mirror_topo_table(ob, mesh, 'u') == -1) {
807     return -1;
808   }
809
810   return mesh_topo_store.index_lookup[index];
811 }
812
813 int mesh_get_x_mirror_vert(Object *ob, Mesh *me_eval, int index, const bool use_topology)
814 {
815   if (use_topology) {
816     return mesh_get_x_mirror_vert_topo(ob, me_eval, index);
817   }
818   else {
819     return mesh_get_x_mirror_vert_spatial(ob, me_eval, index);
820   }
821 }
822
823 static BMVert *editbmesh_get_x_mirror_vert_spatial(Object *ob, BMEditMesh *em, const float co[3])
824 {
825   float vec[3];
826   int i;
827
828   /* ignore nan verts */
829   if ((isfinite(co[0]) == false) || (isfinite(co[1]) == false) || (isfinite(co[2]) == false)) {
830     return NULL;
831   }
832
833   vec[0] = -co[0];
834   vec[1] = co[1];
835   vec[2] = co[2];
836
837   i = ED_mesh_mirror_spatial_table(ob, em, NULL, vec, 'u');
838   if (i != -1) {
839     return BM_vert_at_index(em->bm, i);
840   }
841   return NULL;
842 }
843
844 static BMVert *editbmesh_get_x_mirror_vert_topo(Object *ob,
845                                                 struct BMEditMesh *em,
846                                                 BMVert *eve,
847                                                 int index)
848 {
849   intptr_t poinval;
850   if (ED_mesh_mirror_topo_table(ob, NULL, 'u') == -1) {
851     return NULL;
852   }
853
854   if (index == -1) {
855     BMIter iter;
856     BMVert *v;
857
858     index = 0;
859     BM_ITER_MESH (v, &iter, em->bm, BM_VERTS_OF_MESH) {
860       if (v == eve) {
861         break;
862       }
863       index++;
864     }
865
866     if (index == em->bm->totvert) {
867       return NULL;
868     }
869   }
870
871   poinval = mesh_topo_store.index_lookup[index];
872
873   if (poinval != -1) {
874     return (BMVert *)(poinval);
875   }
876   return NULL;
877 }
878
879 BMVert *editbmesh_get_x_mirror_vert(Object *ob,
880                                     struct BMEditMesh *em,
881                                     BMVert *eve,
882                                     const float co[3],
883                                     int index,
884                                     const bool use_topology)
885 {
886   if (use_topology) {
887     return editbmesh_get_x_mirror_vert_topo(ob, em, eve, index);
888   }
889   else {
890     return editbmesh_get_x_mirror_vert_spatial(ob, em, co);
891   }
892 }
893
894 /**
895  * Wrapper for objectmode/editmode.
896  *
897  * call #BM_mesh_elem_table_ensure first for editmesh.
898  */
899 int ED_mesh_mirror_get_vert(Object *ob, int index)
900 {
901   Mesh *me = ob->data;
902   BMEditMesh *em = me->edit_mesh;
903   bool use_topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0;
904   int index_mirr;
905
906   if (em) {
907     BMVert *eve, *eve_mirr;
908     eve = BM_vert_at_index(em->bm, index);
909     eve_mirr = editbmesh_get_x_mirror_vert(ob, em, eve, eve->co, index, use_topology);
910     index_mirr = eve_mirr ? BM_elem_index_get(eve_mirr) : -1;
911   }
912   else {
913     index_mirr = mesh_get_x_mirror_vert(ob, NULL, index, use_topology);
914   }
915
916   return index_mirr;
917 }
918
919 #if 0
920
921 static float *editmesh_get_mirror_uv(
922     BMEditMesh *em, int axis, float *uv, float *mirrCent, float *face_cent)
923 {
924   float vec[2];
925   float cent_vec[2];
926   float cent[2];
927
928   /* ignore nan verts */
929   if (isnan(uv[0]) || !isfinite(uv[0]) || isnan(uv[1]) || !isfinite(uv[1])) {
930     return NULL;
931   }
932
933   if (axis) {
934     vec[0] = uv[0];
935     vec[1] = -((uv[1]) - mirrCent[1]) + mirrCent[1];
936
937     cent_vec[0] = face_cent[0];
938     cent_vec[1] = -((face_cent[1]) - mirrCent[1]) + mirrCent[1];
939   }
940   else {
941     vec[0] = -((uv[0]) - mirrCent[0]) + mirrCent[0];
942     vec[1] = uv[1];
943
944     cent_vec[0] = -((face_cent[0]) - mirrCent[0]) + mirrCent[0];
945     cent_vec[1] = face_cent[1];
946   }
947
948   /* TODO - Optimize */
949   {
950     BMIter iter;
951     BMFace *efa;
952
953     BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
954       uv_poly_center(efa, cent, cd_loop_uv_offset);
955
956       if ((fabsf(cent[0] - cent_vec[0]) < 0.001f) && (fabsf(cent[1] - cent_vec[1]) < 0.001f)) {
957         BMIter liter;
958         BMLoop *l;
959
960         BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
961           MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
962           if ((fabsf(luv->uv[0] - vec[0]) < 0.001f) && (fabsf(luv->uv[1] - vec[1]) < 0.001f)) {
963             return luv->uv;
964           }
965         }
966       }
967     }
968   }
969
970   return NULL;
971 }
972
973 #endif
974
975 static unsigned int mirror_facehash(const void *ptr)
976 {
977   const MFace *mf = ptr;
978   unsigned int v0, v1;
979
980   if (mf->v4) {
981     v0 = MIN4(mf->v1, mf->v2, mf->v3, mf->v4);
982     v1 = MAX4(mf->v1, mf->v2, mf->v3, mf->v4);
983   }
984   else {
985     v0 = MIN3(mf->v1, mf->v2, mf->v3);
986     v1 = MAX3(mf->v1, mf->v2, mf->v3);
987   }
988
989   return ((v0 * 39) ^ (v1 * 31));
990 }
991
992 static int mirror_facerotation(MFace *a, MFace *b)
993 {
994   if (b->v4) {
995     if (a->v1 == b->v1 && a->v2 == b->v2 && a->v3 == b->v3 && a->v4 == b->v4) {
996       return 0;
997     }
998     else if (a->v4 == b->v1 && a->v1 == b->v2 && a->v2 == b->v3 && a->v3 == b->v4) {
999       return 1;
1000     }
1001     else if (a->v3 == b->v1 && a->v4 == b->v2 && a->v1 == b->v3 && a->v2 == b->v4) {
1002       return 2;
1003     }
1004     else if (a->v2 == b->v1 && a->v3 == b->v2 && a->v4 == b->v3 && a->v1 == b->v4) {
1005       return 3;
1006     }
1007   }
1008   else {
1009     if (a->v1 == b->v1 && a->v2 == b->v2 && a->v3 == b->v3) {
1010       return 0;
1011     }
1012     else if (a->v3 == b->v1 && a->v1 == b->v2 && a->v2 == b->v3) {
1013       return 1;
1014     }
1015     else if (a->v2 == b->v1 && a->v3 == b->v2 && a->v1 == b->v3) {
1016       return 2;
1017     }
1018   }
1019
1020   return -1;
1021 }
1022
1023 static bool mirror_facecmp(const void *a, const void *b)
1024 {
1025   return (mirror_facerotation((MFace *)a, (MFace *)b) == -1);
1026 }
1027
1028 /* This is a Mesh-based copy of mesh_get_x_mirror_faces() */
1029 int *mesh_get_x_mirror_faces(Object *ob, BMEditMesh *em, Mesh *me_eval)
1030 {
1031   Mesh *me = ob->data;
1032   MVert *mv, *mvert;
1033   MFace mirrormf, *mf, *hashmf, *mface;
1034   GHash *fhash;
1035   int *mirrorverts, *mirrorfaces;
1036
1037   BLI_assert(em == NULL); /* Does not work otherwise, currently... */
1038
1039   const bool use_topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0;
1040   const int totvert = me_eval ? me_eval->totvert : me->totvert;
1041   const int totface = me_eval ? me_eval->totface : me->totface;
1042   int a;
1043
1044   mirrorverts = MEM_callocN(sizeof(int) * totvert, "MirrorVerts");
1045   mirrorfaces = MEM_callocN(sizeof(int) * 2 * totface, "MirrorFaces");
1046
1047   mvert = me_eval ? me_eval->mvert : me->mvert;
1048   mface = me_eval ? me_eval->mface : me->mface;
1049
1050   ED_mesh_mirror_spatial_table(ob, em, me_eval, NULL, 's');
1051
1052   for (a = 0, mv = mvert; a < totvert; a++, mv++) {
1053     mirrorverts[a] = mesh_get_x_mirror_vert(ob, me_eval, a, use_topology);
1054   }
1055
1056   ED_mesh_mirror_spatial_table(ob, em, me_eval, NULL, 'e');
1057
1058   fhash = BLI_ghash_new_ex(mirror_facehash, mirror_facecmp, "mirror_facehash gh", me->totface);
1059   for (a = 0, mf = mface; a < totface; a++, mf++) {
1060     BLI_ghash_insert(fhash, mf, mf);
1061   }
1062
1063   for (a = 0, mf = mface; a < totface; a++, mf++) {
1064     mirrormf.v1 = mirrorverts[mf->v3];
1065     mirrormf.v2 = mirrorverts[mf->v2];
1066     mirrormf.v3 = mirrorverts[mf->v1];
1067     mirrormf.v4 = (mf->v4) ? mirrorverts[mf->v4] : 0;
1068
1069     /* make sure v4 is not 0 if a quad */
1070     if (mf->v4 && mirrormf.v4 == 0) {
1071       SWAP(unsigned int, mirrormf.v1, mirrormf.v3);
1072       SWAP(unsigned int, mirrormf.v2, mirrormf.v4);
1073     }
1074
1075     hashmf = BLI_ghash_lookup(fhash, &mirrormf);
1076     if (hashmf) {
1077       mirrorfaces[a * 2] = hashmf - mface;
1078       mirrorfaces[a * 2 + 1] = mirror_facerotation(&mirrormf, hashmf);
1079     }
1080     else {
1081       mirrorfaces[a * 2] = -1;
1082     }
1083   }
1084
1085   BLI_ghash_free(fhash, NULL, NULL);
1086   MEM_freeN(mirrorverts);
1087
1088   return mirrorfaces;
1089 }
1090
1091 /* selection, vertex and face */
1092 /* returns 0 if not found, otherwise 1 */
1093
1094 /**
1095  * Face selection in object mode,
1096  * currently only weight-paint and vertex-paint use this.
1097  *
1098  * \return boolean true == Found
1099  */
1100 bool ED_mesh_pick_face(bContext *C, Object *ob, const int mval[2], uint dist_px, uint *r_index)
1101 {
1102   ViewContext vc;
1103   Mesh *me = ob->data;
1104
1105   BLI_assert(me && GS(me->id.name) == ID_ME);
1106
1107   if (!me || me->totpoly == 0) {
1108     return false;
1109   }
1110
1111   ED_view3d_viewcontext_init(C, &vc);
1112
1113   if (dist_px) {
1114     /* sample rect to increase chances of selecting, so that when clicking
1115      * on an edge in the backbuf, we can still select a face */
1116
1117     ED_view3d_select_id_validate(&vc);
1118
1119     *r_index = ED_view3d_select_id_read_nearest(&vc, mval, 1, me->totpoly + 1, &dist_px);
1120   }
1121   else {
1122     /* sample only on the exact position */
1123     *r_index = ED_view3d_select_id_sample(&vc, mval[0], mval[1]);
1124   }
1125
1126   if ((*r_index) == 0 || (*r_index) > (unsigned int)me->totpoly) {
1127     return false;
1128   }
1129
1130   (*r_index)--;
1131
1132   return true;
1133 }
1134
1135 static void ed_mesh_pick_face_vert__mpoly_find(
1136     /* context */
1137     struct ARegion *ar,
1138     const float mval[2],
1139     /* mesh data (evaluated) */
1140     const MPoly *mp,
1141     const MVert *mvert,
1142     const MLoop *mloop,
1143     /* return values */
1144     float *r_len_best,
1145     int *r_v_idx_best)
1146 {
1147   const MLoop *ml;
1148   int j = mp->totloop;
1149   for (ml = &mloop[mp->loopstart]; j--; ml++) {
1150     float sco[2];
1151     const int v_idx = ml->v;
1152     const float *co = mvert[v_idx].co;
1153     if (ED_view3d_project_float_object(ar, co, sco, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
1154       const float len_test = len_manhattan_v2v2(mval, sco);
1155       if (len_test < *r_len_best) {
1156         *r_len_best = len_test;
1157         *r_v_idx_best = v_idx;
1158       }
1159     }
1160   }
1161 }
1162 /**
1163  * Use when the back buffer stores face index values. but we want a vert.
1164  * This gets the face then finds the closest vertex to mval.
1165  */
1166 bool ED_mesh_pick_face_vert(
1167     bContext *C, Object *ob, const int mval[2], uint dist_px, uint *r_index)
1168 {
1169   Depsgraph *depsgraph = CTX_data_depsgraph(C);
1170   unsigned int poly_index;
1171   Mesh *me = ob->data;
1172
1173   BLI_assert(me && GS(me->id.name) == ID_ME);
1174
1175   if (ED_mesh_pick_face(C, ob, mval, dist_px, &poly_index)) {
1176     Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
1177     Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
1178     struct ARegion *ar = CTX_wm_region(C);
1179
1180     /* derived mesh to find deformed locations */
1181     Mesh *me_eval = mesh_get_eval_final(
1182         depsgraph, scene_eval, ob_eval, &CD_MASK_BAREMESH_ORIGINDEX);
1183
1184     int v_idx_best = ORIGINDEX_NONE;
1185
1186     /* find the vert closest to 'mval' */
1187     const float mval_f[2] = {UNPACK2(mval)};
1188     float len_best = FLT_MAX;
1189
1190     MPoly *me_eval_mpoly;
1191     MLoop *me_eval_mloop;
1192     MVert *me_eval_mvert;
1193     unsigned int me_eval_mpoly_len;
1194     const int *index_mp_to_orig;
1195
1196     me_eval_mpoly = me_eval->mpoly;
1197     me_eval_mloop = me_eval->mloop;
1198     me_eval_mvert = me_eval->mvert;
1199
1200     me_eval_mpoly_len = me_eval->totpoly;
1201
1202     index_mp_to_orig = CustomData_get_layer(&me_eval->pdata, CD_ORIGINDEX);
1203
1204     /* tag all verts using this face */
1205     if (index_mp_to_orig) {
1206       unsigned int i;
1207
1208       for (i = 0; i < me_eval_mpoly_len; i++) {
1209         if (index_mp_to_orig[i] == poly_index) {
1210           ed_mesh_pick_face_vert__mpoly_find(
1211               ar, mval_f, &me_eval_mpoly[i], me_eval_mvert, me_eval_mloop, &len_best, &v_idx_best);
1212         }
1213       }
1214     }
1215     else {
1216       if (poly_index < me_eval_mpoly_len) {
1217         ed_mesh_pick_face_vert__mpoly_find(ar,
1218                                            mval_f,
1219                                            &me_eval_mpoly[poly_index],
1220                                            me_eval_mvert,
1221                                            me_eval_mloop,
1222                                            &len_best,
1223                                            &v_idx_best);
1224       }
1225     }
1226
1227     /* map 'dm -> me' r_index if possible */
1228     if (v_idx_best != ORIGINDEX_NONE) {
1229       const int *index_mv_to_orig;
1230       index_mv_to_orig = CustomData_get_layer(&me_eval->vdata, CD_ORIGINDEX);
1231       if (index_mv_to_orig) {
1232         v_idx_best = index_mv_to_orig[v_idx_best];
1233       }
1234     }
1235
1236     if ((v_idx_best != ORIGINDEX_NONE) && (v_idx_best < me->totvert)) {
1237       *r_index = v_idx_best;
1238       return true;
1239     }
1240   }
1241
1242   return false;
1243 }
1244
1245 /**
1246  * Vertex selection in object mode,
1247  * currently only weight paint uses this.
1248  *
1249  * \return boolean true == Found
1250  */
1251 typedef struct VertPickData {
1252   const MVert *mvert;
1253   const float *mval_f; /* [2] */
1254   ARegion *ar;
1255
1256   /* runtime */
1257   float len_best;
1258   int v_idx_best;
1259 } VertPickData;
1260
1261 static void ed_mesh_pick_vert__mapFunc(void *userData,
1262                                        int index,
1263                                        const float co[3],
1264                                        const float UNUSED(no_f[3]),
1265                                        const short UNUSED(no_s[3]))
1266 {
1267   VertPickData *data = userData;
1268   if ((data->mvert[index].flag & ME_HIDE) == 0) {
1269     float sco[2];
1270
1271     if (ED_view3d_project_float_object(data->ar, co, sco, V3D_PROJ_TEST_CLIP_DEFAULT) ==
1272         V3D_PROJ_RET_OK) {
1273       const float len = len_manhattan_v2v2(data->mval_f, sco);
1274       if (len < data->len_best) {
1275         data->len_best = len;
1276         data->v_idx_best = index;
1277       }
1278     }
1279   }
1280 }
1281 bool ED_mesh_pick_vert(
1282     bContext *C, Object *ob, const int mval[2], uint dist_px, bool use_zbuf, uint *r_index)
1283 {
1284   ViewContext vc;
1285   Mesh *me = ob->data;
1286
1287   BLI_assert(me && GS(me->id.name) == ID_ME);
1288
1289   if (!me || me->totvert == 0) {
1290     return false;
1291   }
1292
1293   ED_view3d_viewcontext_init(C, &vc);
1294
1295   if (use_zbuf) {
1296     if (dist_px > 0) {
1297       /* sample rect to increase chances of selecting, so that when clicking
1298        * on an face in the backbuf, we can still select a vert */
1299
1300       ED_view3d_select_id_validate(&vc);
1301
1302       *r_index = ED_view3d_select_id_read_nearest(&vc, mval, 1, me->totvert + 1, &dist_px);
1303     }
1304     else {
1305       /* sample only on the exact position */
1306       *r_index = ED_view3d_select_id_sample(&vc, mval[0], mval[1]);
1307     }
1308
1309     if ((*r_index) == 0 || (*r_index) > (uint)me->totvert) {
1310       return false;
1311     }
1312
1313     (*r_index)--;
1314   }
1315   else {
1316     Scene *scene_eval = DEG_get_evaluated_scene(vc.depsgraph);
1317     Object *ob_eval = DEG_get_evaluated_object(vc.depsgraph, ob);
1318
1319     /* derived mesh to find deformed locations */
1320     Mesh *me_eval = mesh_get_eval_final(vc.depsgraph, scene_eval, ob_eval, &CD_MASK_BAREMESH);
1321     ARegion *ar = vc.ar;
1322     RegionView3D *rv3d = ar->regiondata;
1323
1324     /* find the vert closest to 'mval' */
1325     const float mval_f[2] = {(float)mval[0], (float)mval[1]};
1326
1327     VertPickData data = {NULL};
1328
1329     ED_view3d_init_mats_rv3d(ob, rv3d);
1330
1331     if (me_eval == NULL) {
1332       return false;
1333     }
1334
1335     /* setup data */
1336     data.mvert = me->mvert;
1337     data.ar = ar;
1338     data.mval_f = mval_f;
1339     data.len_best = FLT_MAX;
1340     data.v_idx_best = -1;
1341
1342     BKE_mesh_foreach_mapped_vert(me_eval, ed_mesh_pick_vert__mapFunc, &data, MESH_FOREACH_NOP);
1343
1344     if (data.v_idx_best == -1) {
1345       return false;
1346     }
1347
1348     *r_index = data.v_idx_best;
1349   }
1350
1351   return true;
1352 }
1353
1354 MDeformVert *ED_mesh_active_dvert_get_em(Object *ob, BMVert **r_eve)
1355 {
1356   if (ob->mode & OB_MODE_EDIT && ob->type == OB_MESH && ob->defbase.first) {
1357     Mesh *me = ob->data;
1358     BMesh *bm = me->edit_mesh->bm;
1359     const int cd_dvert_offset = CustomData_get_offset(&bm->vdata, CD_MDEFORMVERT);
1360
1361     if (cd_dvert_offset != -1) {
1362       BMVert *eve = BM_mesh_active_vert_get(bm);
1363
1364       if (eve) {
1365         if (r_eve) {
1366           *r_eve = eve;
1367         }
1368         return BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset);
1369       }
1370     }
1371   }
1372
1373   if (r_eve) {
1374     *r_eve = NULL;
1375   }
1376   return NULL;
1377 }
1378
1379 MDeformVert *ED_mesh_active_dvert_get_ob(Object *ob, int *r_index)
1380 {
1381   Mesh *me = ob->data;
1382   int index = BKE_mesh_mselect_active_get(me, ME_VSEL);
1383   if (r_index) {
1384     *r_index = index;
1385   }
1386   if (index == -1 || me->dvert == NULL) {
1387     return NULL;
1388   }
1389   else {
1390     return me->dvert + index;
1391   }
1392 }
1393
1394 MDeformVert *ED_mesh_active_dvert_get_only(Object *ob)
1395 {
1396   if (ob->type == OB_MESH) {
1397     if (ob->mode & OB_MODE_EDIT) {
1398       return ED_mesh_active_dvert_get_em(ob, NULL);
1399     }
1400     else {
1401       return ED_mesh_active_dvert_get_ob(ob, NULL);
1402     }
1403   }
1404   else {
1405     return NULL;
1406   }
1407 }
1408
1409 void EDBM_mesh_stats_multi(struct Object **objects,
1410                            const uint objects_len,
1411                            int totelem[3],
1412                            int totelem_sel[3])
1413 {
1414   if (totelem) {
1415     totelem[0] = 0;
1416     totelem[1] = 0;
1417     totelem[2] = 0;
1418   }
1419   if (totelem_sel) {
1420     totelem_sel[0] = 0;
1421     totelem_sel[1] = 0;
1422     totelem_sel[2] = 0;
1423   }
1424
1425   for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
1426     Object *obedit = objects[ob_index];
1427     BMEditMesh *em = BKE_editmesh_from_object(obedit);
1428     BMesh *bm = em->bm;
1429     if (totelem) {
1430       totelem[0] += bm->totvert;
1431       totelem[1] += bm->totedge;
1432       totelem[2] += bm->totface;
1433     }
1434     if (totelem_sel) {
1435       totelem_sel[0] += bm->totvertsel;
1436       totelem_sel[1] += bm->totedgesel;
1437       totelem_sel[2] += bm->totfacesel;
1438     }
1439   }
1440 }
1441
1442 void EDBM_mesh_elem_index_ensure_multi(Object **objects, const uint objects_len, const char htype)
1443 {
1444   int elem_offset[4] = {0, 0, 0, 0};
1445   for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
1446     Object *obedit = objects[ob_index];
1447     BMEditMesh *em = BKE_editmesh_from_object(obedit);
1448     BMesh *bm = em->bm;
1449     BM_mesh_elem_index_ensure_ex(bm, htype, elem_offset);
1450   }
1451 }