Merge branch 'master' into blender2.8
[blender.git] / source / blender / editors / mesh / editmesh_tools.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2004 by Blender Foundation.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): Joseph Eagar
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/editors/mesh/editmesh_tools.c
29  *  \ingroup edmesh
30  */
31
32 #include <stddef.h>
33
34 #include "MEM_guardedalloc.h"
35
36 #include "DNA_key_types.h"
37 #include "DNA_material_types.h"
38 #include "DNA_mesh_types.h"
39 #include "DNA_meshdata_types.h"
40 #include "DNA_modifier_types.h"
41 #include "DNA_object_types.h"
42 #include "DNA_scene_types.h"
43
44 #include "BLI_bitmap.h"
45 #include "BLI_heap.h"
46 #include "BLI_listbase.h"
47 #include "BLI_linklist.h"
48 #include "BLI_linklist_stack.h"
49 #include "BLI_noise.h"
50 #include "BLI_math.h"
51 #include "BLI_rand.h"
52 #include "BLI_sort_utils.h"
53 #include "BLI_string.h"
54
55 #include "BKE_layer.h"
56 #include "BKE_material.h"
57 #include "BKE_context.h"
58 #include "BKE_deform.h"
59 #include "BKE_report.h"
60 #include "BKE_texture.h"
61 #include "BKE_main.h"
62 #include "BKE_mesh.h"
63 #include "BKE_editmesh.h"
64
65 #include "DEG_depsgraph.h"
66 #include "DEG_depsgraph_build.h"
67
68 #include "BLT_translation.h"
69
70 #include "RNA_define.h"
71 #include "RNA_access.h"
72 #include "RNA_enum_types.h"
73
74 #include "WM_api.h"
75 #include "WM_types.h"
76
77 #include "ED_mesh.h"
78 #include "ED_object.h"
79 #include "ED_screen.h"
80 #include "ED_transform.h"
81 #include "ED_transform_snap_object_context.h"
82 #include "ED_uvedit.h"
83 #include "ED_view3d.h"
84
85 #include "RE_render_ext.h"
86
87 #include "UI_interface.h"
88 #include "UI_resources.h"
89
90 #include "mesh_intern.h"  /* own include */
91
92 #include "bmesh_tools.h"
93
94 #define USE_FACE_CREATE_SEL_EXTEND
95
96 /* -------------------------------------------------------------------- */
97 /** \name Subdivide Operator
98  * \{ */
99
100 static int edbm_subdivide_exec(bContext *C, wmOperator *op)
101 {
102         const int cuts = RNA_int_get(op->ptr, "number_cuts");
103         const float smooth = RNA_float_get(op->ptr, "smoothness");
104         const float fractal = RNA_float_get(op->ptr, "fractal") / 2.5f;
105         const float along_normal = RNA_float_get(op->ptr, "fractal_along_normal");
106
107         if (RNA_boolean_get(op->ptr, "ngon") &&
108             RNA_enum_get(op->ptr, "quadcorner") == SUBD_CORNER_STRAIGHT_CUT)
109         {
110                 RNA_enum_set(op->ptr, "quadcorner", SUBD_CORNER_INNERVERT);
111         }
112         const int quad_corner_type = RNA_enum_get(op->ptr, "quadcorner");
113         const bool use_quad_tri = !RNA_boolean_get(op->ptr, "ngon");
114         const int seed = RNA_int_get(op->ptr, "seed");
115
116         ViewLayer *view_layer = CTX_data_view_layer(C);
117         uint objects_len = 0;
118         Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
119
120         for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
121                 Object *obedit = objects[ob_index];
122                 BMEditMesh *em = BKE_editmesh_from_object(obedit);
123
124                 if (!(em->bm->totedgesel || em->bm->totfacesel)) {
125                         continue;
126                 }
127
128                 BM_mesh_esubdivide(
129                         em->bm, BM_ELEM_SELECT,
130                         smooth, SUBD_FALLOFF_LIN, false,
131                         fractal, along_normal,
132                         cuts,
133                         SUBDIV_SELECT_ORIG, quad_corner_type,
134                         use_quad_tri, true, false,
135                         seed);
136
137                 EDBM_update_generic(em, true, true);
138         }
139
140         MEM_freeN(objects);
141
142         return OPERATOR_FINISHED;
143 }
144
145 /* Note, these values must match delete_mesh() event values */
146 static const EnumPropertyItem prop_mesh_cornervert_types[] = {
147         {SUBD_CORNER_INNERVERT,     "INNERVERT", 0,      "Inner Vert", ""},
148         {SUBD_CORNER_PATH,          "PATH", 0,           "Path", ""},
149         {SUBD_CORNER_STRAIGHT_CUT,  "STRAIGHT_CUT", 0,   "Straight Cut", ""},
150         {SUBD_CORNER_FAN,           "FAN", 0,            "Fan", ""},
151         {0, NULL, 0, NULL, NULL}
152 };
153
154 void MESH_OT_subdivide(wmOperatorType *ot)
155 {
156         PropertyRNA *prop;
157
158         /* identifiers */
159         ot->name = "Subdivide";
160         ot->description = "Subdivide selected edges";
161         ot->idname = "MESH_OT_subdivide";
162
163         /* api callbacks */
164         ot->exec = edbm_subdivide_exec;
165         ot->poll = ED_operator_editmesh;
166
167         /* flags */
168         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
169
170         /* properties */
171         prop = RNA_def_int(ot->srna, "number_cuts", 1, 1, 100, "Number of Cuts", "", 1, 10);
172         /* avoid re-using last var because it can cause _very_ high poly meshes and annoy users (or worse crash) */
173         RNA_def_property_flag(prop, PROP_SKIP_SAVE);
174
175         RNA_def_float(ot->srna, "smoothness", 0.0f, 0.0f, 1e3f, "Smoothness", "Smoothness factor", 0.0f, 1.0f);
176
177         WM_operatortype_props_advanced_begin(ot);
178
179         RNA_def_boolean(ot->srna, "ngon", true, "Create N-Gons", "When disabled, newly created faces are limited to 3-4 sided faces");
180         RNA_def_enum(ot->srna, "quadcorner", prop_mesh_cornervert_types, SUBD_CORNER_STRAIGHT_CUT,
181                      "Quad Corner Type", "How to subdivide quad corners (anything other than Straight Cut will prevent ngons)");
182
183         RNA_def_float(ot->srna, "fractal", 0.0f, 0.0f, 1e6f, "Fractal", "Fractal randomness factor", 0.0f, 1000.0f);
184         RNA_def_float(ot->srna, "fractal_along_normal", 0.0f, 0.0f, 1.0f,
185                       "Along Normal", "Apply fractal displacement along normal only", 0.0f, 1.0f);
186         RNA_def_int(ot->srna, "seed", 0, 0, INT_MAX, "Random Seed", "Seed for the random number generator", 0, 255);
187 }
188
189 /** \} */
190
191 /* -------------------------------------------------------------------- */
192 /** \name Edge Ring Subdivide Operator
193  *
194  * Bridge code shares props.
195  *
196  * \{ */
197
198 struct EdgeRingOpSubdProps {
199         int interp_mode;
200         int cuts;
201         float smooth;
202
203         int profile_shape;
204         float profile_shape_factor;
205 };
206
207
208 static void mesh_operator_edgering_props(wmOperatorType *ot, const int cuts_min, const int cuts_default)
209 {
210         /* Note, these values must match delete_mesh() event values */
211         static const EnumPropertyItem prop_subd_edgering_types[] = {
212                 {SUBD_RING_INTERP_LINEAR, "LINEAR", 0, "Linear", ""},
213                 {SUBD_RING_INTERP_PATH, "PATH", 0, "Blend Path", ""},
214                 {SUBD_RING_INTERP_SURF, "SURFACE", 0, "Blend Surface", ""},
215                 {0, NULL, 0, NULL, NULL}
216         };
217
218         PropertyRNA *prop;
219
220         prop = RNA_def_int(ot->srna, "number_cuts", cuts_default, 0, 1000, "Number of Cuts", "", cuts_min, 64);
221         RNA_def_property_flag(prop, PROP_SKIP_SAVE);
222
223         RNA_def_enum(ot->srna, "interpolation", prop_subd_edgering_types, SUBD_RING_INTERP_PATH,
224                      "Interpolation", "Interpolation method");
225
226         RNA_def_float(ot->srna, "smoothness", 1.0f, 0.0f, 1e3f,
227                       "Smoothness", "Smoothness factor", 0.0f, 2.0f);
228
229         /* profile-shape */
230         RNA_def_float(ot->srna, "profile_shape_factor", 0.0f, -1e3f, 1e3f,
231                       "Profile Factor", "How much intermediary new edges are shrunk/expanded", -2.0f, 2.0f);
232
233         prop = RNA_def_property(ot->srna, "profile_shape", PROP_ENUM, PROP_NONE);
234         RNA_def_property_enum_items(prop, rna_enum_proportional_falloff_curve_only_items);
235         RNA_def_property_enum_default(prop, PROP_SMOOTH);
236         RNA_def_property_ui_text(prop, "Profile Shape", "Shape of the profile");
237         RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_CURVE); /* Abusing id_curve :/ */
238 }
239
240 static void mesh_operator_edgering_props_get(wmOperator *op, struct EdgeRingOpSubdProps *op_props)
241 {
242         op_props->interp_mode = RNA_enum_get(op->ptr, "interpolation");
243         op_props->cuts = RNA_int_get(op->ptr, "number_cuts");
244         op_props->smooth = RNA_float_get(op->ptr, "smoothness");
245
246         op_props->profile_shape = RNA_enum_get(op->ptr, "profile_shape");
247         op_props->profile_shape_factor = RNA_float_get(op->ptr, "profile_shape_factor");
248 }
249
250 static int edbm_subdivide_edge_ring_exec(bContext *C, wmOperator *op)
251 {
252
253         ViewLayer *view_layer = CTX_data_view_layer(C);
254         uint objects_len = 0;
255         Object * *objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
256         struct EdgeRingOpSubdProps op_props;
257
258         mesh_operator_edgering_props_get(op, &op_props);
259
260         for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
261                 Object * obedit = objects[ob_index];
262                 BMEditMesh * em = BKE_editmesh_from_object(obedit);
263
264                 if (em->bm->totedgesel == 0) {
265                         continue;
266                 }
267
268                 if (!EDBM_op_callf(
269                         em, op,
270                         "subdivide_edgering edges=%he interp_mode=%i cuts=%i smooth=%f "
271                         "profile_shape=%i profile_shape_factor=%f",
272                         BM_ELEM_SELECT, op_props.interp_mode, op_props.cuts, op_props.smooth,
273                         op_props.profile_shape, op_props.profile_shape_factor))
274                 {
275                         continue;
276                 }
277
278                 EDBM_update_generic(em, true, true);
279         }
280
281         MEM_freeN(objects);
282         return OPERATOR_FINISHED;
283 }
284
285 void MESH_OT_subdivide_edgering(wmOperatorType *ot)
286 {
287         /* identifiers */
288         ot->name = "Subdivide Edge-Ring";
289         ot->description = "";
290         ot->idname = "MESH_OT_subdivide_edgering";
291
292         /* api callbacks */
293         ot->exec = edbm_subdivide_edge_ring_exec;
294         ot->poll = ED_operator_editmesh;
295
296         /* flags */
297         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
298
299         /* properties */
300         mesh_operator_edgering_props(ot, 1, 10);
301 }
302
303 /** \} */
304
305 /* -------------------------------------------------------------------- */
306 /** \name Un-Subdivide Operator
307  * \{ */
308
309 static int edbm_unsubdivide_exec(bContext *C, wmOperator *op)
310 {
311         const int iterations = RNA_int_get(op->ptr, "iterations");
312         ViewLayer *view_layer = CTX_data_view_layer(C);
313         uint objects_len = 0;
314         Object **objects = BKE_view_layer_array_from_objects_in_edit_mode(view_layer, &objects_len);
315         for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
316                 Object *obedit = objects[ob_index];
317                 BMEditMesh *em = BKE_editmesh_from_object(obedit);
318
319                 if ((em->bm->totvertsel == 0) &&
320                     (em->bm->totedgesel == 0) &&
321                     (em->bm->totfacesel == 0))
322                 {
323                         continue;
324                 }
325
326                 BMOperator bmop;
327                 EDBM_op_init(em, &bmop, op,
328                        "unsubdivide verts=%hv iterations=%i", BM_ELEM_SELECT, iterations);
329
330                 BMO_op_exec(em->bm, &bmop);
331
332                 if (!EDBM_op_finish(em, &bmop, op, true)) {
333                         continue;
334                 }
335
336                 if ((em->selectmode & SCE_SELECT_VERTEX) == 0) {
337                         EDBM_selectmode_flush_ex(em, SCE_SELECT_VERTEX);  /* need to flush vert->face first */
338                 }
339                 EDBM_selectmode_flush(em);
340
341                 EDBM_update_generic(em, true, true);
342         }
343         MEM_freeN(objects);
344
345         return OPERATOR_FINISHED;
346 }
347
348 void MESH_OT_unsubdivide(wmOperatorType *ot)
349 {
350         /* identifiers */
351         ot->name = "Un-Subdivide";
352         ot->description = "UnSubdivide selected edges & faces";
353         ot->idname = "MESH_OT_unsubdivide";
354
355         /* api callbacks */
356         ot->exec = edbm_unsubdivide_exec;
357         ot->poll = ED_operator_editmesh;
358
359         /* flags */
360         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
361
362         /* props */
363         RNA_def_int(ot->srna, "iterations", 2, 1, 1000, "Iterations", "Number of times to unsubdivide", 1, 100);
364 }
365
366 void EDBM_project_snap_verts(bContext *C, ARegion *ar, BMEditMesh *em)
367 {
368         Main *bmain = CTX_data_main(C);
369         Object *obedit = em->ob;
370         BMIter iter;
371         BMVert *eve;
372
373         ED_view3d_init_mats_rv3d(obedit, ar->regiondata);
374
375         struct SnapObjectContext *snap_context = ED_transform_snap_object_context_create_view3d(
376                 bmain, CTX_data_scene(C), CTX_data_depsgraph(C), 0,
377                 ar, CTX_wm_view3d(C));
378
379         BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
380                 if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
381                         float mval[2], co_proj[3];
382                         if (ED_view3d_project_float_object(ar, eve->co, mval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
383                                 if (ED_transform_snap_object_project_view3d(
384                                         snap_context,
385                                         SCE_SNAP_MODE_FACE,
386                                         &(const struct SnapObjectParams){
387                                             .snap_select = SNAP_NOT_ACTIVE,
388                                             .use_object_edit_cage = false,
389                                             .use_occlusion_test = true,
390                                         },
391                                         mval, NULL,
392                                         co_proj, NULL))
393                                 {
394                                         mul_v3_m4v3(eve->co, obedit->imat, co_proj);
395                                 }
396                         }
397                 }
398         }
399
400         ED_transform_snap_object_context_destroy(snap_context);
401 }
402
403 /** \} */
404
405 /* -------------------------------------------------------------------- */
406 /** \name Delete Operator
407  * \{ */
408
409 /* Note, these values must match delete_mesh() event values */
410 enum {
411         MESH_DELETE_VERT      = 0,
412         MESH_DELETE_EDGE      = 1,
413         MESH_DELETE_FACE      = 2,
414         MESH_DELETE_EDGE_FACE = 3,
415         MESH_DELETE_ONLY_FACE = 4,
416 };
417
418 static void edbm_report_delete_info(ReportList *reports, const int totelem_old[3], const int totelem_new[3])
419 {
420         BKE_reportf(reports, RPT_INFO,
421                     "Removed: %d vertices, %d edges, %d faces",
422                     totelem_old[0] - totelem_new[0], totelem_old[1] - totelem_new[1], totelem_old[2] - totelem_new[2]);
423 }
424
425 static int edbm_delete_exec(bContext *C, wmOperator *op)
426 {
427         ViewLayer *view_layer = CTX_data_view_layer(C);
428
429         uint objects_len = 0;
430         Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
431         bool changed_multi = false;
432
433         for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
434                 Object *obedit = objects[ob_index];
435                 BMEditMesh *em = BKE_editmesh_from_object(obedit);
436                 const int type = RNA_enum_get(op->ptr, "type");
437
438                 switch (type) {
439                         case MESH_DELETE_VERT: /* Erase Vertices */
440                                 if (!(em->bm->totvertsel &&
441                                       EDBM_op_callf(em, op, "delete geom=%hv context=%i", BM_ELEM_SELECT, DEL_VERTS)))
442                                 {
443                                         continue;
444                                 }
445                                 break;
446                         case MESH_DELETE_EDGE: /* Erase Edges */
447                                 if (!(em->bm->totedgesel &&
448                                       EDBM_op_callf(em, op, "delete geom=%he context=%i", BM_ELEM_SELECT, DEL_EDGES)))
449                                 {
450                                         continue;
451                                 }
452                                 break;
453                         case MESH_DELETE_FACE: /* Erase Faces */
454                                 if (!(em->bm->totfacesel &&
455                                       EDBM_op_callf(em, op, "delete geom=%hf context=%i", BM_ELEM_SELECT, DEL_FACES)))
456                                 {
457                                         continue;
458                                 }
459                                 break;
460                         case MESH_DELETE_EDGE_FACE:
461                                 /* Edges and Faces */
462                                 if (!((em->bm->totedgesel || em->bm->totfacesel) &&
463                                       EDBM_op_callf(em, op, "delete geom=%hef context=%i", BM_ELEM_SELECT, DEL_EDGESFACES)))
464                                 {
465                                         continue;
466                                 }
467                                 break;
468                         case MESH_DELETE_ONLY_FACE:
469                                 /* Only faces. */
470                                 if (!(em->bm->totfacesel &&
471                                       EDBM_op_callf(em, op, "delete geom=%hf context=%i", BM_ELEM_SELECT, DEL_ONLYFACES)))
472                                 {
473                                         continue;
474                                 }
475                                 break;
476                         default:
477                                 BLI_assert(0);
478                                 break;
479                 }
480
481                 changed_multi = true;
482
483                 EDBM_flag_disable_all(em, BM_ELEM_SELECT);
484
485                 EDBM_update_generic(em, true, true);
486         }
487
488         MEM_freeN(objects);
489
490         return changed_multi ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
491 }
492
493 void MESH_OT_delete(wmOperatorType *ot)
494 {
495         static const EnumPropertyItem prop_mesh_delete_types[] = {
496                 {MESH_DELETE_VERT,      "VERT",      0, "Vertices", ""},
497                 {MESH_DELETE_EDGE,      "EDGE",      0, "Edges", ""},
498                 {MESH_DELETE_FACE,      "FACE",      0, "Faces", ""},
499                 {MESH_DELETE_EDGE_FACE, "EDGE_FACE", 0, "Only Edges & Faces", ""},
500                 {MESH_DELETE_ONLY_FACE, "ONLY_FACE", 0, "Only Faces", ""},
501                 {0, NULL, 0, NULL, NULL}
502         };
503
504         /* identifiers */
505         ot->name = "Delete";
506         ot->description = "Delete selected vertices, edges or faces";
507         ot->idname = "MESH_OT_delete";
508
509         /* api callbacks */
510         ot->invoke = WM_menu_invoke;
511         ot->exec = edbm_delete_exec;
512
513         ot->poll = ED_operator_editmesh;
514
515         /* flags */
516         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
517
518         /* props */
519         ot->prop = RNA_def_enum(ot->srna, "type", prop_mesh_delete_types, MESH_DELETE_VERT,
520                                 "Type", "Method used for deleting mesh data");
521         RNA_def_property_flag(ot->prop, PROP_HIDDEN | PROP_SKIP_SAVE);
522 }
523
524 /** \} */
525
526 /* -------------------------------------------------------------------- */
527 /** \name Delete Loose Operator
528  * \{ */
529
530 static bool bm_face_is_loose(BMFace *f)
531 {
532         BMLoop *l_iter, *l_first;
533
534         l_iter = l_first = BM_FACE_FIRST_LOOP(f);
535         do {
536                 if (!BM_edge_is_boundary(l_iter->e)) {
537                         return false;
538                 }
539         } while ((l_iter = l_iter->next) != l_first);
540
541         return true;
542 }
543
544 static int edbm_delete_loose_exec(bContext *C, wmOperator *op)
545 {
546         ViewLayer *view_layer = CTX_data_view_layer(C);
547         int totelem_old_sel[3];
548         int totelem_old[3];
549
550         uint objects_len = 0;
551         Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
552
553         EDBM_mesh_stats_multi(objects, objects_len, totelem_old, totelem_old_sel);
554
555         const bool use_verts = (RNA_boolean_get(op->ptr, "use_verts") && totelem_old_sel[0]);
556         const bool use_edges = (RNA_boolean_get(op->ptr, "use_edges") && totelem_old_sel[1]);
557         const bool use_faces = (RNA_boolean_get(op->ptr, "use_faces") && totelem_old_sel[2]);
558
559         for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
560                 Object *obedit = objects[ob_index];
561
562                 BMEditMesh *em = BKE_editmesh_from_object(obedit);
563                 BMesh *bm = em->bm;
564                 BMIter iter;
565
566                 BM_mesh_elem_hflag_disable_all(bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_TAG, false);
567
568                 if (use_faces) {
569                         BMFace *f;
570
571                         BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
572                                 if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
573                                         BM_elem_flag_set(f, BM_ELEM_TAG, bm_face_is_loose(f));
574                                 }
575                         }
576
577                         BM_mesh_delete_hflag_context(bm, BM_ELEM_TAG, DEL_FACES);
578                 }
579
580                 if (use_edges) {
581                         BMEdge *e;
582
583                         BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
584                                 if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
585                                         BM_elem_flag_set(e, BM_ELEM_TAG, BM_edge_is_wire(e));
586                                 }
587                         }
588
589                         BM_mesh_delete_hflag_context(bm, BM_ELEM_TAG, DEL_EDGES);
590                 }
591
592                 if (use_verts) {
593                         BMVert *v;
594
595                         BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
596                                 if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
597                                         BM_elem_flag_set(v, BM_ELEM_TAG, (v->e == NULL));
598                                 }
599                         }
600
601                         BM_mesh_delete_hflag_context(bm, BM_ELEM_TAG, DEL_VERTS);
602                 }
603
604                 EDBM_flag_disable_all(em, BM_ELEM_SELECT);
605
606                 EDBM_update_generic(em, true, true);
607         }
608
609         int totelem_new[3];
610         EDBM_mesh_stats_multi(objects, objects_len, totelem_new, NULL);
611
612         edbm_report_delete_info(op->reports, totelem_old, totelem_new);
613
614         MEM_freeN(objects);
615
616         return OPERATOR_FINISHED;
617 }
618
619
620 void MESH_OT_delete_loose(wmOperatorType *ot)
621 {
622         /* identifiers */
623         ot->name = "Delete Loose";
624         ot->description = "Delete loose vertices, edges or faces";
625         ot->idname = "MESH_OT_delete_loose";
626
627         /* api callbacks */
628         ot->exec = edbm_delete_loose_exec;
629
630         ot->poll = ED_operator_editmesh;
631
632         /* flags */
633         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
634
635         /* props */
636         RNA_def_boolean(ot->srna, "use_verts", true, "Vertices", "Remove loose vertices");
637         RNA_def_boolean(ot->srna, "use_edges", true, "Edges", "Remove loose edges");
638         RNA_def_boolean(ot->srna, "use_faces", false, "Faces", "Remove loose faces");
639 }
640
641 /** \} */
642
643 /* -------------------------------------------------------------------- */
644 /** \name Collapse Edge Operator
645  * \{ */
646
647 static int edbm_collapse_edge_exec(bContext *C, wmOperator *op)
648 {
649         ViewLayer *view_layer = CTX_data_view_layer(C);
650         uint objects_len = 0;
651         Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
652         for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
653                 Object *obedit = objects[ob_index];
654                 BMEditMesh *em = BKE_editmesh_from_object(obedit);
655
656                 if (em->bm->totedgesel == 0) {
657                         continue;
658                 }
659
660                 if (!EDBM_op_callf(em, op, "collapse edges=%he uvs=%b", BM_ELEM_SELECT, true)) {
661                         continue;
662                 }
663
664                 EDBM_update_generic(em, true, true);
665         }
666         MEM_freeN(objects);
667
668         return OPERATOR_FINISHED;
669 }
670
671 void MESH_OT_edge_collapse(wmOperatorType *ot)
672 {
673         /* identifiers */
674         ot->name = "Edge Collapse";
675         ot->description = "Collapse selected edges";
676         ot->idname = "MESH_OT_edge_collapse";
677
678         /* api callbacks */
679         ot->exec = edbm_collapse_edge_exec;
680         ot->poll = ED_operator_editmesh;
681
682         /* flags */
683         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
684 }
685
686 /** \} */
687
688 /* -------------------------------------------------------------------- */
689 /** \name Create Edge/Face Operator
690  * \{ */
691
692 static bool edbm_add_edge_face__smooth_get(BMesh *bm)
693 {
694         BMEdge *e;
695         BMIter iter;
696
697         unsigned int vote_on_smooth[2] = {0, 0};
698
699         BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
700                 if (BM_elem_flag_test(e, BM_ELEM_SELECT) && e->l) {
701                         vote_on_smooth[BM_elem_flag_test_bool(e->l->f, BM_ELEM_SMOOTH)]++;
702                 }
703         }
704
705         return (vote_on_smooth[0] < vote_on_smooth[1]);
706 }
707
708 #ifdef USE_FACE_CREATE_SEL_EXTEND
709 /**
710  * Function used to get a fixed number of edges linked to a vertex that passes a test function.
711  * This is used so we can request all boundary edges connected to a vertex for eg.
712  */
713 static int edbm_add_edge_face_exec__vert_edge_lookup(
714         BMVert *v, BMEdge *e_used, BMEdge **e_arr, const int e_arr_len,
715         bool (* func)(const BMEdge *))
716 {
717         BMIter iter;
718         BMEdge *e_iter;
719         int i = 0;
720         BM_ITER_ELEM (e_iter, &iter, v, BM_EDGES_OF_VERT) {
721                 if (BM_elem_flag_test(e_iter, BM_ELEM_HIDDEN) == false) {
722                         if ((e_used == NULL) || (e_used != e_iter)) {
723                                 if (func(e_iter)) {
724                                         e_arr[i++] = e_iter;
725                                         if (i >= e_arr_len) {
726                                                 break;
727                                         }
728                                 }
729                         }
730                 }
731         }
732         return i;
733 }
734
735 static BMElem *edbm_add_edge_face_exec__tricky_extend_sel(BMesh *bm)
736 {
737         BMIter iter;
738         bool found = false;
739
740         if (bm->totvertsel == 1 && bm->totedgesel == 0 && bm->totfacesel == 0) {
741                 /* first look for 2 boundary edges */
742                 BMVert *v;
743
744                 BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
745                         if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
746                                 found = true;
747                                 break;
748                         }
749                 }
750
751                 if (found) {
752                         BMEdge *ed_pair[3];
753                         if (
754                             ((edbm_add_edge_face_exec__vert_edge_lookup(v, NULL, ed_pair, 3, BM_edge_is_wire) == 2) &&
755                              (BM_edge_share_face_check(ed_pair[0], ed_pair[1]) == false)) ||
756
757                             ((edbm_add_edge_face_exec__vert_edge_lookup(v, NULL, ed_pair, 3, BM_edge_is_boundary) == 2) &&
758                              (BM_edge_share_face_check(ed_pair[0], ed_pair[1]) == false))
759                             )
760                         {
761                                 BMEdge *e_other = BM_edge_exists(
762                                         BM_edge_other_vert(ed_pair[0], v),
763                                         BM_edge_other_vert(ed_pair[1], v));
764                                 BM_edge_select_set(bm, ed_pair[0], true);
765                                 BM_edge_select_set(bm, ed_pair[1], true);
766                                 if (e_other) {
767                                         BM_edge_select_set(bm, e_other, true);
768                                 }
769                                 return (BMElem *)v;
770                         }
771                 }
772         }
773         else if (bm->totvertsel == 2 && bm->totedgesel == 1 && bm->totfacesel == 0) {
774                 /* first look for 2 boundary edges */
775                 BMEdge *e;
776
777                 BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
778                         if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
779                                 found = true;
780                                 break;
781                         }
782                 }
783                 if (found) {
784                         BMEdge *ed_pair_v1[2];
785                         BMEdge *ed_pair_v2[2];
786                         if (
787                             ((edbm_add_edge_face_exec__vert_edge_lookup(e->v1, e, ed_pair_v1, 2, BM_edge_is_wire) == 1) &&
788                              (edbm_add_edge_face_exec__vert_edge_lookup(e->v2, e, ed_pair_v2, 2, BM_edge_is_wire) == 1) &&
789                              (BM_edge_share_face_check(e, ed_pair_v1[0]) == false) &&
790                              (BM_edge_share_face_check(e, ed_pair_v2[0]) == false)) ||
791
792 #if 1  /* better support mixed cases [#37203] */
793                             ((edbm_add_edge_face_exec__vert_edge_lookup(e->v1, e, ed_pair_v1, 2, BM_edge_is_wire)     == 1) &&
794                              (edbm_add_edge_face_exec__vert_edge_lookup(e->v2, e, ed_pair_v2, 2, BM_edge_is_boundary) == 1) &&
795                              (BM_edge_share_face_check(e, ed_pair_v1[0]) == false) &&
796                              (BM_edge_share_face_check(e, ed_pair_v2[0]) == false)) ||
797
798                             ((edbm_add_edge_face_exec__vert_edge_lookup(e->v1, e, ed_pair_v1, 2, BM_edge_is_boundary) == 1) &&
799                              (edbm_add_edge_face_exec__vert_edge_lookup(e->v2, e, ed_pair_v2, 2, BM_edge_is_wire)     == 1) &&
800                              (BM_edge_share_face_check(e, ed_pair_v1[0]) == false) &&
801                              (BM_edge_share_face_check(e, ed_pair_v2[0]) == false)) ||
802 #endif
803
804                             ((edbm_add_edge_face_exec__vert_edge_lookup(e->v1, e, ed_pair_v1, 2, BM_edge_is_boundary) == 1) &&
805                              (edbm_add_edge_face_exec__vert_edge_lookup(e->v2, e, ed_pair_v2, 2, BM_edge_is_boundary) == 1) &&
806                              (BM_edge_share_face_check(e, ed_pair_v1[0]) == false) &&
807                              (BM_edge_share_face_check(e, ed_pair_v2[0]) == false))
808                             )
809                         {
810                                 BMVert *v1_other = BM_edge_other_vert(ed_pair_v1[0], e->v1);
811                                 BMVert *v2_other = BM_edge_other_vert(ed_pair_v2[0], e->v2);
812                                 BMEdge *e_other = (v1_other != v2_other) ? BM_edge_exists(v1_other, v2_other) : NULL;
813                                 BM_edge_select_set(bm, ed_pair_v1[0], true);
814                                 BM_edge_select_set(bm, ed_pair_v2[0], true);
815                                 if (e_other) {
816                                         BM_edge_select_set(bm, e_other, true);
817                                 }
818                                 return (BMElem *)e;
819                         }
820                 }
821         }
822
823         return NULL;
824 }
825 static void edbm_add_edge_face_exec__tricky_finalize_sel(BMesh *bm, BMElem *ele_desel, BMFace *f)
826 {
827         /* now we need to find the edge that isnt connected to this element */
828         BM_select_history_clear(bm);
829
830         /* Notes on hidden geometry:
831          * - un-hide the face since its possible hidden was copied when copying surrounding face attributes.
832          * - un-hide before adding to select history
833          *   since we may extend into an existing, hidden vert/edge.
834          */
835
836         BM_elem_flag_disable(f, BM_ELEM_HIDDEN);
837         BM_face_select_set(bm, f, false);
838
839         if (ele_desel->head.htype == BM_VERT) {
840                 BMLoop *l = BM_face_vert_share_loop(f, (BMVert *)ele_desel);
841                 BLI_assert(f->len == 3);
842                 BM_vert_select_set(bm, (BMVert *)ele_desel, false);
843                 BM_edge_select_set(bm, l->next->e, true);
844                 BM_select_history_store(bm, l->next->e);
845         }
846         else {
847                 BMLoop *l = BM_face_edge_share_loop(f, (BMEdge *)ele_desel);
848                 BLI_assert(f->len == 4 || f->len == 3);
849
850                 BM_edge_select_set(bm, (BMEdge *)ele_desel, false);
851                 if (f->len == 4) {
852                         BMEdge *e_active = l->next->next->e;
853                         BM_elem_flag_disable(e_active, BM_ELEM_HIDDEN);
854                         BM_edge_select_set(bm, e_active, true);
855                         BM_select_history_store(bm, e_active);
856                 }
857                 else {
858                         BMVert *v_active = l->next->next->v;
859                         BM_elem_flag_disable(v_active, BM_ELEM_HIDDEN);
860                         BM_vert_select_set(bm, v_active, true);
861                         BM_select_history_store(bm, v_active);
862                 }
863         }
864 }
865 #endif  /* USE_FACE_CREATE_SEL_EXTEND */
866
867 static int edbm_add_edge_face_exec(bContext *C, wmOperator *op)
868 {
869         /* when this is used to dissolve we could avoid this, but checking isnt too slow */
870
871         ViewLayer *view_layer = CTX_data_view_layer(C);
872         uint objects_len = 0;
873         Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
874         for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
875                 Object *obedit = objects[ob_index];
876                 BMEditMesh *em = BKE_editmesh_from_object(obedit);
877
878                 if ((em->bm->totvertsel == 0) &&
879                     (em->bm->totedgesel == 0) &&
880                     (em->bm->totvertsel == 0))
881                 {
882                         continue;
883                 }
884
885                 bool use_smooth = edbm_add_edge_face__smooth_get(em->bm);
886                 int totedge_orig = em->bm->totedge;
887                 int totface_orig = em->bm->totface;
888
889                 BMOperator bmop;
890 #ifdef USE_FACE_CREATE_SEL_EXTEND
891                 BMElem *ele_desel;
892                 BMFace *ele_desel_face;
893
894                 /* be extra clever, figure out if a partial selection should be extended so we can create geometry
895                  * with single vert or single edge selection */
896                 ele_desel = edbm_add_edge_face_exec__tricky_extend_sel(em->bm);
897 #endif
898                 if (!EDBM_op_init(
899                             em, &bmop, op,
900                             "contextual_create geom=%hfev mat_nr=%i use_smooth=%b",
901                             BM_ELEM_SELECT, em->mat_nr, use_smooth))
902                 {
903                         continue;
904                 }
905
906                 BMO_op_exec(em->bm, &bmop);
907
908                 /* cancel if nothing was done */
909                 if ((totedge_orig == em->bm->totedge) &&
910                     (totface_orig == em->bm->totface))
911                 {
912                         EDBM_op_finish(em, &bmop, op, true);
913                         continue;
914                 }
915 #ifdef USE_FACE_CREATE_SEL_EXTEND
916                 /* normally we would want to leave the new geometry selected,
917                  * but being able to press F many times to add geometry is too useful! */
918                 if (ele_desel &&
919                     (BMO_slot_buffer_count(bmop.slots_out, "faces.out") == 1) &&
920                     (ele_desel_face = BMO_slot_buffer_get_first(bmop.slots_out, "faces.out")))
921                 {
922                         edbm_add_edge_face_exec__tricky_finalize_sel(em->bm, ele_desel, ele_desel_face);
923                 }
924                 else
925 #endif
926                 {
927                         /* Newly created faces may include existing hidden edges,
928                          * copying face data from surrounding, may have copied hidden face flag too.
929                          *
930                          * Important that faces use flushing since 'edges.out' wont include hidden edges that already existed.
931                          */
932                         BMO_slot_buffer_hflag_disable(em->bm, bmop.slots_out, "faces.out", BM_FACE, BM_ELEM_HIDDEN, true);
933                         BMO_slot_buffer_hflag_disable(em->bm, bmop.slots_out, "edges.out", BM_EDGE, BM_ELEM_HIDDEN, false);
934
935                         BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "faces.out", BM_FACE, BM_ELEM_SELECT, true);
936                         BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "edges.out", BM_EDGE, BM_ELEM_SELECT, true);
937                 }
938
939                 if (!EDBM_op_finish(em, &bmop, op, true)) {
940                         continue;
941                 }
942
943                 EDBM_update_generic(em, true, true);
944         }
945         MEM_freeN(objects);
946
947         return OPERATOR_FINISHED;
948 }
949
950 void MESH_OT_edge_face_add(wmOperatorType *ot)
951 {
952         /* identifiers */
953         ot->name = "Make Edge/Face";
954         ot->description = "Add an edge or face to selected";
955         ot->idname = "MESH_OT_edge_face_add";
956
957         /* api callbacks */
958         ot->exec = edbm_add_edge_face_exec;
959         ot->poll = ED_operator_editmesh;
960
961         /* flags */
962         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
963 }
964
965 /** \} */
966
967 /* -------------------------------------------------------------------- */
968 /** \name Mark Edge (Seam) Operator
969  * \{ */
970
971 static int edbm_mark_seam_exec(bContext *C, wmOperator *op)
972 {
973         Scene *scene = CTX_data_scene(C);
974         ViewLayer *view_layer = CTX_data_view_layer(C);
975         BMEdge *eed;
976         BMIter iter;
977         const bool clear = RNA_boolean_get(op->ptr, "clear");
978
979         uint objects_len = 0;
980         Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
981         for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
982                 Object *obedit = objects[ob_index];
983                 BMEditMesh *em = BKE_editmesh_from_object(obedit);
984                 BMesh *bm = em->bm;
985
986                 if (bm->totedgesel == 0) {
987                         continue;
988                 }
989
990                 Mesh *me = ((Mesh *)obedit->data);
991
992                 /* auto-enable seams drawing */
993                 if (clear == 0) {
994                         me->drawflag |= ME_DRAWSEAMS;
995                 }
996
997                 if (clear) {
998                         BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
999                                 if (!BM_elem_flag_test(eed, BM_ELEM_SELECT) || BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
1000                                         continue;
1001                                 }
1002
1003                                 BM_elem_flag_disable(eed, BM_ELEM_SEAM);
1004                         }
1005                 }
1006                 else {
1007                         BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
1008                                 if (!BM_elem_flag_test(eed, BM_ELEM_SELECT) || BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
1009                                         continue;
1010                                 }
1011                                 BM_elem_flag_enable(eed, BM_ELEM_SEAM);
1012                         }
1013                 }
1014
1015                 ED_uvedit_live_unwrap(scene, obedit);
1016                 EDBM_update_generic(em, true, false);
1017         }
1018         MEM_freeN(objects);
1019
1020         return OPERATOR_FINISHED;
1021 }
1022
1023 void MESH_OT_mark_seam(wmOperatorType *ot)
1024 {
1025         PropertyRNA *prop;
1026
1027         /* identifiers */
1028         ot->name = "Mark Seam";
1029         ot->idname = "MESH_OT_mark_seam";
1030         ot->description = "(Un)mark selected edges as a seam";
1031
1032         /* api callbacks */
1033         ot->exec = edbm_mark_seam_exec;
1034         ot->poll = ED_operator_editmesh;
1035
1036         /* flags */
1037         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1038
1039         prop = RNA_def_boolean(ot->srna, "clear", 0, "Clear", "");
1040         RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
1041
1042         WM_operatortype_props_advanced_begin(ot);
1043 }
1044
1045 /** \} */
1046
1047 /* -------------------------------------------------------------------- */
1048 /** \name Mark Edge (Sharp) Operator
1049  * \{ */
1050
1051 static int edbm_mark_sharp_exec(bContext *C, wmOperator *op)
1052 {
1053         BMEdge *eed;
1054         BMIter iter;
1055         const bool clear = RNA_boolean_get(op->ptr, "clear");
1056         const bool use_verts = RNA_boolean_get(op->ptr, "use_verts");
1057         ViewLayer *view_layer = CTX_data_view_layer(C);
1058
1059         uint objects_len = 0;
1060         Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
1061         for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
1062                 Object *obedit = objects[ob_index];
1063                 BMEditMesh *em = BKE_editmesh_from_object(obedit);
1064                 BMesh *bm = em->bm;
1065                 Mesh *me = ((Mesh *)obedit->data);
1066
1067                 if (bm->totedgesel == 0) {
1068                         continue;
1069                 }
1070
1071                 /* auto-enable sharp edge drawing */
1072                 if (clear == 0) {
1073                         me->drawflag |= ME_DRAWSHARP;
1074                 }
1075
1076                 BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
1077                         if (use_verts) {
1078                                 if (!(BM_elem_flag_test(eed->v1, BM_ELEM_SELECT) || BM_elem_flag_test(eed->v2, BM_ELEM_SELECT))) {
1079                                         continue;
1080                                 }
1081                         }
1082                         else if (!BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
1083                                 continue;
1084                         }
1085
1086                         BM_elem_flag_set(eed, BM_ELEM_SMOOTH, clear);
1087                 }
1088
1089                 EDBM_update_generic(em, true, false);
1090         }
1091         MEM_freeN(objects);
1092
1093         return OPERATOR_FINISHED;
1094 }
1095
1096 void MESH_OT_mark_sharp(wmOperatorType *ot)
1097 {
1098         PropertyRNA *prop;
1099
1100         /* identifiers */
1101         ot->name = "Mark Sharp";
1102         ot->idname = "MESH_OT_mark_sharp";
1103         ot->description = "(Un)mark selected edges as sharp";
1104
1105         /* api callbacks */
1106         ot->exec = edbm_mark_sharp_exec;
1107         ot->poll = ED_operator_editmesh;
1108
1109         /* flags */
1110         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1111
1112         prop = RNA_def_boolean(ot->srna, "clear", false, "Clear", "");
1113         RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
1114         prop = RNA_def_boolean(ot->srna, "use_verts", false, "Vertices",
1115                                "Consider vertices instead of edges to select which edges to (un)tag as sharp");
1116         RNA_def_property_flag(prop, PROP_SKIP_SAVE);
1117 }
1118
1119 static bool edbm_connect_vert_pair(BMEditMesh *em, wmOperator *op)
1120 {
1121         BMesh *bm = em->bm;
1122         BMOperator bmop;
1123         const int verts_len = bm->totvertsel;
1124         bool is_pair = (verts_len == 2);
1125         int len = 0;
1126         bool check_degenerate = true;
1127
1128         BMVert **verts;
1129         bool checks_succeded = true;
1130
1131         /* sanity check */
1132         if (!is_pair) {
1133                 return false;
1134         }
1135
1136         verts = MEM_mallocN(sizeof(*verts) * verts_len, __func__);
1137         {
1138                 BMIter iter;
1139                 BMVert *v;
1140                 int i = 0;
1141
1142                 BM_ITER_MESH(v, &iter, bm, BM_VERTS_OF_MESH) {
1143                         if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
1144                                 verts[i++] = v;
1145                         }
1146                 }
1147
1148                 if (BM_vert_pair_share_face_check_cb(
1149                             verts[0], verts[1],
1150                             BM_elem_cb_check_hflag_disabled_simple(BMFace *, BM_ELEM_HIDDEN)))
1151                 {
1152                         check_degenerate = false;
1153                         is_pair = false;
1154                 }
1155         }
1156
1157         if (is_pair) {
1158                 if (!EDBM_op_init(
1159                             em, &bmop, op,
1160                             "connect_vert_pair verts=%eb verts_exclude=%hv faces_exclude=%hf",
1161                             verts, verts_len, BM_ELEM_HIDDEN, BM_ELEM_HIDDEN))
1162                 {
1163                         checks_succeded = false;
1164                 }
1165         }
1166         else {
1167                 if (!EDBM_op_init(
1168                             em, &bmop, op,
1169                             "connect_verts verts=%eb faces_exclude=%hf check_degenerate=%b",
1170                             verts, verts_len, BM_ELEM_HIDDEN, check_degenerate))
1171                 {
1172                         checks_succeded = false;
1173                 }
1174         }
1175         if (checks_succeded) {
1176                 BMO_op_exec(bm, &bmop);
1177                 len = BMO_slot_get(bmop.slots_out, "edges.out")->len;
1178
1179                 if (len && is_pair) {
1180                         /* new verts have been added, we have to select the edges, not just flush */
1181                         BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "edges.out", BM_EDGE, BM_ELEM_SELECT, true);
1182                 }
1183
1184                 if (!EDBM_op_finish(em, &bmop, op, true)) {
1185                         len = 0;
1186                 }
1187                 else {
1188                         EDBM_selectmode_flush(em);  /* so newly created edges get the selection state from the vertex */
1189
1190                         EDBM_update_generic(em, true, true);
1191                 }
1192         }
1193         MEM_freeN(verts);
1194
1195         return len;
1196 }
1197
1198 static int edbm_vert_connect_exec(bContext *C, wmOperator *op)
1199 {
1200         ViewLayer *view_layer = CTX_data_view_layer(C);
1201         uint objects_len = 0;
1202         uint failed_objects_len = 0;
1203         Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
1204
1205         for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
1206                 Object *obedit = objects[ob_index];
1207                 BMEditMesh *em = BKE_editmesh_from_object(obedit);
1208
1209                 if (!edbm_connect_vert_pair(em, op)) {
1210                         failed_objects_len++;
1211                 }
1212         }
1213         MEM_freeN(objects);
1214         return failed_objects_len == objects_len ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
1215 }
1216
1217 void MESH_OT_vert_connect(wmOperatorType *ot)
1218 {
1219         /* identifiers */
1220         ot->name = "Vertex Connect";
1221         ot->idname = "MESH_OT_vert_connect";
1222         ot->description = "Connect selected vertices of faces, splitting the face";
1223
1224         /* api callbacks */
1225         ot->exec = edbm_vert_connect_exec;
1226         ot->poll = ED_operator_editmesh;
1227
1228         /* flags */
1229         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1230 }
1231
1232 /** \} */
1233
1234 /* -------------------------------------------------------------------- */
1235 /** \name Split Concave Faces Operator
1236  * \{ */
1237
1238 /**
1239  * check that endpoints are verts and only have a single selected edge connected.
1240  */
1241 static bool bm_vert_is_select_history_open(BMesh *bm)
1242 {
1243         BMEditSelection *ele_a = bm->selected.first;
1244         BMEditSelection *ele_b = bm->selected.last;
1245         if ((ele_a->htype == BM_VERT) &&
1246             (ele_b->htype == BM_VERT))
1247         {
1248                 if ((BM_iter_elem_count_flag(BM_EDGES_OF_VERT, (BMVert *)ele_a->ele, BM_ELEM_SELECT, true) == 1) &&
1249                     (BM_iter_elem_count_flag(BM_EDGES_OF_VERT, (BMVert *)ele_b->ele, BM_ELEM_SELECT, true) == 1))
1250                 {
1251                         return true;
1252                 }
1253         }
1254
1255         return false;
1256 }
1257
1258 static bool bm_vert_connect_pair(BMesh *bm, BMVert *v_a, BMVert *v_b)
1259 {
1260         BMOperator bmop;
1261         BMVert **verts;
1262         const int totedge_orig = bm->totedge;
1263
1264         BMO_op_init(bm, &bmop, BMO_FLAG_DEFAULTS, "connect_vert_pair");
1265
1266         verts = BMO_slot_buffer_alloc(&bmop, bmop.slots_in, "verts", 2);
1267         verts[0] = v_a;
1268         verts[1] = v_b;
1269
1270         BM_vert_normal_update(verts[0]);
1271         BM_vert_normal_update(verts[1]);
1272
1273         BMO_op_exec(bm, &bmop);
1274         BMO_slot_buffer_hflag_enable(bm, bmop.slots_out, "edges.out", BM_EDGE, BM_ELEM_SELECT, true);
1275         BMO_op_finish(bm, &bmop);
1276         return (bm->totedge != totedge_orig);
1277 }
1278
1279 static bool bm_vert_connect_select_history(BMesh *bm)
1280 {
1281         /* Logic is as follows:
1282          *
1283          * - If there are any isolated/wire verts - connect as edges.
1284          * - Otherwise connect faces.
1285          * - If all edges have been created already, closed the loop.
1286          */
1287         if (BLI_listbase_count_at_most(&bm->selected, 2) == 2 && (bm->totvertsel > 2)) {
1288                 BMEditSelection *ese;
1289                 int tot = 0;
1290                 bool changed = false;
1291                 bool has_wire = false;
1292                 // bool all_verts;
1293
1294                 /* ensure all verts have history */
1295                 for (ese = bm->selected.first; ese; ese = ese->next, tot++) {
1296                         BMVert *v;
1297                         if (ese->htype != BM_VERT) {
1298                                 break;
1299                         }
1300                         v = (BMVert *)ese->ele;
1301                         if ((has_wire == false) && ((v->e == NULL) || BM_vert_is_wire(v))) {
1302                                 has_wire = true;
1303                         }
1304                 }
1305                 // all_verts = (ese == NULL);
1306
1307                 if (has_wire == false) {
1308                         /* all verts have faces , connect verts via faces! */
1309                         if (tot == bm->totvertsel) {
1310                                 BMEditSelection *ese_last;
1311                                 ese_last = bm->selected.first;
1312                                 ese = ese_last->next;
1313
1314                                 do {
1315
1316                                         if (BM_edge_exists((BMVert *)ese_last->ele, (BMVert *)ese->ele)) {
1317                                                 /* pass, edge exists (and will be selected) */
1318                                         }
1319                                         else {
1320                                                 changed |= bm_vert_connect_pair(bm, (BMVert *)ese_last->ele, (BMVert *)ese->ele);
1321                                         }
1322                                 } while ((void)
1323                                          (ese_last = ese),
1324                                          (ese = ese->next));
1325
1326                                 if (changed) {
1327                                         return true;
1328                                 }
1329                         }
1330
1331                         if (changed == false) {
1332                                 /* existing loops: close the selection */
1333                                 if (bm_vert_is_select_history_open(bm)) {
1334                                         changed |= bm_vert_connect_pair(
1335                                                 bm,
1336                                                 (BMVert *)((BMEditSelection *)bm->selected.first)->ele,
1337                                                 (BMVert *)((BMEditSelection *)bm->selected.last)->ele);
1338
1339                                         if (changed) {
1340                                                 return true;
1341                                         }
1342                                 }
1343                         }
1344                 }
1345
1346                 else {
1347                         /* no faces, simply connect the verts by edges */
1348                         BMEditSelection *ese_prev;
1349                         ese_prev = bm->selected.first;
1350                         ese = ese_prev->next;
1351
1352
1353                         do {
1354                                 if (BM_edge_exists((BMVert *)ese_prev->ele, (BMVert *)ese->ele)) {
1355                                         /* pass, edge exists (and will be selected) */
1356                                 }
1357                                 else {
1358                                         BMEdge *e;
1359                                         e = BM_edge_create(bm, (BMVert *)ese_prev->ele, (BMVert *)ese->ele, NULL, 0);
1360                                         BM_edge_select_set(bm, e, true);
1361                                         changed = true;
1362                                 }
1363                         } while ((void)
1364                                  (ese_prev = ese),
1365                                  (ese = ese->next));
1366
1367                         if (changed == false) {
1368                                 /* existing loops: close the selection */
1369                                 if (bm_vert_is_select_history_open(bm)) {
1370                                         BMEdge *e;
1371                                         ese_prev = bm->selected.first;
1372                                         ese = bm->selected.last;
1373                                         e = BM_edge_create(bm, (BMVert *)ese_prev->ele, (BMVert *)ese->ele, NULL, 0);
1374                                         BM_edge_select_set(bm, e, true);
1375                                 }
1376                         }
1377
1378                         return true;
1379                 }
1380         }
1381
1382         return false;
1383 }
1384
1385 /**
1386  * Convert an edge selection to a temp vertex selection
1387  * (which must be cleared after use as a path to connect).
1388  */
1389 static bool bm_vert_connect_select_history_edge_to_vert_path(BMesh *bm, ListBase *r_selected)
1390 {
1391         ListBase selected_orig = {NULL, NULL};
1392         BMEditSelection *ese;
1393         int edges_len = 0;
1394         bool side = false;
1395
1396         /* first check all edges are OK */
1397         for (ese = bm->selected.first; ese; ese = ese->next) {
1398                 if (ese->htype == BM_EDGE) {
1399                         edges_len += 1;
1400                 }
1401                 else {
1402                         return false;
1403                 }
1404         }
1405         /* if this is a mixed selection, bail out! */
1406         if (bm->totedgesel != edges_len) {
1407                 return false;
1408         }
1409
1410         SWAP(ListBase, bm->selected, selected_orig);
1411
1412         /* convert edge selection into 2 ordered loops (where the first edge ends up in the middle) */
1413         for (ese = selected_orig.first; ese; ese = ese->next) {
1414                 BMEdge *e_curr = (BMEdge *)ese->ele;
1415                 BMEdge *e_prev = ese->prev ? (BMEdge *)ese->prev->ele : NULL;
1416                 BMLoop *l_curr;
1417                 BMLoop *l_prev;
1418                 BMVert *v;
1419
1420                 if (e_prev) {
1421                         BMFace *f = BM_edge_pair_share_face_by_len(e_curr, e_prev, &l_curr, &l_prev, true);
1422                         if (f) {
1423                                 if ((e_curr->v1 != l_curr->v) == (e_prev->v1 != l_prev->v)) {
1424                                         side = !side;
1425                                 }
1426                         }
1427                         else if (is_quad_flip_v3(e_curr->v1->co, e_curr->v2->co, e_prev->v2->co, e_prev->v1->co)) {
1428                                 side = !side;
1429                         }
1430                 }
1431
1432                 v = (&e_curr->v1)[side];
1433                 if (!bm->selected.last || (BMVert *)((BMEditSelection *)bm->selected.last)->ele != v) {
1434                         BM_select_history_store_notest(bm, v);
1435                 }
1436
1437                 v = (&e_curr->v1)[!side];
1438                 if (!bm->selected.first || (BMVert *)((BMEditSelection *)bm->selected.first)->ele != v) {
1439                         BM_select_history_store_head_notest(bm, v);
1440                 }
1441
1442                 e_prev = e_curr;
1443         }
1444
1445         *r_selected = bm->selected;
1446         bm->selected = selected_orig;
1447
1448         return true;
1449 }
1450
1451 static int edbm_vert_connect_path_exec(bContext *C, wmOperator *op)
1452 {
1453         ViewLayer *view_layer = CTX_data_view_layer(C);
1454         uint objects_len = 0;
1455         uint failed_selection_order_len = 0;
1456         uint failed_connect_len = 0;
1457         Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
1458
1459         for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
1460                 Object *obedit = objects[ob_index];
1461                 BMEditMesh *em = BKE_editmesh_from_object(obedit);
1462                 BMesh *bm = em->bm;
1463                 const bool is_pair = (em->bm->totvertsel == 2);
1464                 ListBase selected_orig = {NULL, NULL};
1465
1466                 if (bm->totvertsel == 0) {
1467                         continue;
1468                 }
1469
1470                 /* when there is only 2 vertices, we can ignore selection order */
1471                 if (is_pair) {
1472                         if (!edbm_connect_vert_pair(em, op)) {
1473                                 failed_connect_len++;
1474                         }
1475                         continue;
1476                 }
1477
1478                 if (bm->selected.first) {
1479                         BMEditSelection *ese = bm->selected.first;
1480                         if (ese->htype == BM_EDGE) {
1481                                 if (bm_vert_connect_select_history_edge_to_vert_path(bm, &selected_orig)) {
1482                                         SWAP(ListBase, bm->selected, selected_orig);
1483                                 }
1484                         }
1485                 }
1486
1487                 if (bm_vert_connect_select_history(bm)) {
1488                         EDBM_selectmode_flush(em);
1489                         EDBM_update_generic(em, true, true);
1490                 }
1491                 else {
1492                         failed_selection_order_len++;
1493                 }
1494
1495                 if (!BLI_listbase_is_empty(&selected_orig)) {
1496                         BM_select_history_clear(bm);
1497                         bm->selected = selected_orig;
1498                 }
1499         }
1500
1501         MEM_freeN(objects);
1502
1503         if (failed_selection_order_len == objects_len) {
1504                 BKE_report(op->reports, RPT_ERROR, "Invalid selection order");
1505                 return OPERATOR_CANCELLED;
1506         }
1507         else if (failed_connect_len == objects_len) {
1508                 BKE_report(op->reports, RPT_ERROR, "Could not connect vertices");
1509                 return OPERATOR_CANCELLED;
1510         }
1511
1512         return OPERATOR_FINISHED;
1513 }
1514
1515 void MESH_OT_vert_connect_path(wmOperatorType *ot)
1516 {
1517         /* identifiers */
1518         ot->name = "Vertex Connect Path";
1519         ot->idname = "MESH_OT_vert_connect_path";
1520         ot->description = "Connect vertices by their selection order, creating edges, splitting faces";
1521
1522         /* api callbacks */
1523         ot->exec = edbm_vert_connect_path_exec;
1524         ot->poll = ED_operator_editmesh;
1525
1526         /* flags */
1527         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1528 }
1529
1530 static int edbm_vert_connect_concave_exec(bContext *C, wmOperator *op)
1531 {
1532         ViewLayer *view_layer = CTX_data_view_layer(C);
1533         uint objects_len = 0;
1534         Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
1535         for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
1536                 Object *obedit = objects[ob_index];
1537                 BMEditMesh *em = BKE_editmesh_from_object(obedit);
1538
1539                 if (em->bm->totfacesel == 0) {
1540                         continue;
1541                 }
1542
1543                 if (!EDBM_op_call_and_selectf(
1544                              em, op,
1545                              "faces.out", true,
1546                              "connect_verts_concave faces=%hf",
1547                              BM_ELEM_SELECT))
1548                 {
1549                         continue;
1550                 }
1551                 EDBM_update_generic(em, true, true);
1552         }
1553
1554         MEM_freeN(objects);
1555         return OPERATOR_FINISHED;
1556 }
1557
1558 void MESH_OT_vert_connect_concave(wmOperatorType *ot)
1559 {
1560         /* identifiers */
1561         ot->name = "Split Concave Faces";
1562         ot->idname = "MESH_OT_vert_connect_concave";
1563         ot->description = "Make all faces convex";
1564
1565         /* api callbacks */
1566         ot->exec = edbm_vert_connect_concave_exec;
1567         ot->poll = ED_operator_editmesh;
1568
1569         /* flags */
1570         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1571 }
1572
1573 /** \} */
1574
1575 /* -------------------------------------------------------------------- */
1576 /** \name Split Non-Planar Faces Operator
1577  * \{ */
1578
1579 static int edbm_vert_connect_nonplaner_exec(bContext *C, wmOperator *op)
1580 {
1581         ViewLayer *view_layer = CTX_data_view_layer(C);
1582         const float angle_limit = RNA_float_get(op->ptr, "angle_limit");
1583         uint objects_len = 0;
1584         Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
1585
1586         for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
1587                 Object *obedit = objects[ob_index];
1588                 BMEditMesh *em = BKE_editmesh_from_object(obedit);
1589
1590                 if (em->bm->totfacesel == 0) {
1591                         continue;
1592                 }
1593
1594                 if (!EDBM_op_call_and_selectf(
1595                             em, op,
1596                             "faces.out", true,
1597                             "connect_verts_nonplanar faces=%hf angle_limit=%f",
1598                             BM_ELEM_SELECT, angle_limit))
1599                 {
1600                         continue;
1601                 }
1602
1603                 EDBM_update_generic(em, true, true);
1604         }
1605         MEM_freeN(objects);
1606
1607         return OPERATOR_FINISHED;
1608 }
1609
1610 void MESH_OT_vert_connect_nonplanar(wmOperatorType *ot)
1611 {
1612         PropertyRNA *prop;
1613
1614         /* identifiers */
1615         ot->name = "Split Non-Planar Faces";
1616         ot->idname = "MESH_OT_vert_connect_nonplanar";
1617         ot->description = "Split non-planar faces that exceed the angle threshold";
1618
1619         /* api callbacks */
1620         ot->exec = edbm_vert_connect_nonplaner_exec;
1621         ot->poll = ED_operator_editmesh;
1622
1623         /* flags */
1624         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1625
1626         /* props */
1627         prop = RNA_def_float_rotation(ot->srna, "angle_limit", 0, NULL, 0.0f, DEG2RADF(180.0f),
1628                                       "Max Angle", "Angle limit", 0.0f, DEG2RADF(180.0f));
1629         RNA_def_property_float_default(prop, DEG2RADF(5.0f));
1630 }
1631
1632 /** \} */
1633
1634 /* -------------------------------------------------------------------- */
1635 /** \name Make Planar Faces Operator
1636  * \{ */
1637
1638 static int edbm_face_make_planar_exec(bContext *C, wmOperator *op)
1639 {
1640         ViewLayer *view_layer = CTX_data_view_layer(C);
1641         uint objects_len = 0;
1642         Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
1643
1644         const int repeat = RNA_int_get(op->ptr, "repeat");
1645         const float fac = RNA_float_get(op->ptr, "factor");
1646
1647         for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
1648                 Object *obedit = objects[ob_index];
1649                 BMEditMesh *em = BKE_editmesh_from_object(obedit);
1650                 if (em->bm->totfacesel == 0) {
1651                         continue;
1652                 }
1653
1654                 if (!EDBM_op_callf(
1655                             em, op, "planar_faces faces=%hf iterations=%i factor=%f",
1656                             BM_ELEM_SELECT, repeat, fac))
1657                 {
1658                         continue;
1659                 }
1660
1661                 EDBM_update_generic(em, true, true);
1662         }
1663         MEM_freeN(objects);
1664
1665         return OPERATOR_FINISHED;
1666 }
1667
1668 void MESH_OT_face_make_planar(wmOperatorType *ot)
1669 {
1670         /* identifiers */
1671         ot->name = "Make Planar Faces";
1672         ot->idname = "MESH_OT_face_make_planar";
1673         ot->description = "Flatten selected faces";
1674
1675         /* api callbacks */
1676         ot->exec = edbm_face_make_planar_exec;
1677         ot->poll = ED_operator_editmesh;
1678
1679         /* flags */
1680         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1681
1682         /* props */
1683         RNA_def_float(ot->srna, "factor", 1.0f, -10.0f, 10.0f, "Factor", "", 0.0f, 1.0f);
1684         RNA_def_int(ot->srna, "repeat", 1, 1, 10000, "Iterations", "", 1, 200);
1685 }
1686
1687 /** \} */
1688
1689 /* -------------------------------------------------------------------- */
1690 /** \name Split Edge Operator
1691  * \{ */
1692
1693 static int edbm_edge_split_exec(bContext *C, wmOperator *op)
1694 {
1695         ViewLayer *view_layer = CTX_data_view_layer(C);
1696         uint objects_len = 0;
1697         Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
1698         for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
1699                 Object *obedit = objects[ob_index];
1700                 BMEditMesh *em = BKE_editmesh_from_object(obedit);
1701                 if (em->bm->totedgesel == 0) {
1702                         continue;
1703                 }
1704
1705                 if (!EDBM_op_call_and_selectf(
1706                             em, op,
1707                             "edges.out", false,
1708                             "split_edges edges=%he",
1709                             BM_ELEM_SELECT))
1710                 {
1711                         continue;
1712                 }
1713
1714                 if (em->selectmode == SCE_SELECT_FACE) {
1715                         EDBM_select_flush(em);
1716                 }
1717
1718                 EDBM_update_generic(em, true, true);
1719         }
1720         MEM_freeN(objects);
1721
1722         return OPERATOR_FINISHED;
1723 }
1724
1725 void MESH_OT_edge_split(wmOperatorType *ot)
1726 {
1727         /* identifiers */
1728         ot->name = "Edge Split";
1729         ot->idname = "MESH_OT_edge_split";
1730         ot->description = "Split selected edges so that each neighbor face gets its own copy";
1731
1732         /* api callbacks */
1733         ot->exec = edbm_edge_split_exec;
1734         ot->poll = ED_operator_editmesh;
1735
1736         /* flags */
1737         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1738 }
1739
1740 /** \} */
1741
1742 /* -------------------------------------------------------------------- */
1743 /** \name Duplicate Operator
1744  * \{ */
1745
1746 static int edbm_duplicate_exec(bContext *C, wmOperator *op)
1747 {
1748         ViewLayer *view_layer = CTX_data_view_layer(C);
1749         uint objects_len = 0;
1750         Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
1751
1752         for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
1753                 Object *obedit = objects[ob_index];
1754                 BMEditMesh *em = BKE_editmesh_from_object(obedit);
1755                 if (em->bm->totvertsel == 0) {
1756                         continue;
1757                 }
1758
1759                 BMOperator bmop;
1760                 BMesh *bm = em->bm;
1761
1762                 EDBM_op_init(
1763                         em, &bmop, op,
1764                         "duplicate geom=%hvef use_select_history=%b",
1765                         BM_ELEM_SELECT, true);
1766
1767                 BMO_op_exec(bm, &bmop);
1768
1769                 /* de-select all would clear otherwise */
1770                 BM_SELECT_HISTORY_BACKUP(bm);
1771
1772                 EDBM_flag_disable_all(em, BM_ELEM_SELECT);
1773
1774                 BMO_slot_buffer_hflag_enable(bm, bmop.slots_out, "geom.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, true);
1775
1776                 /* rebuild editselection */
1777                 BM_SELECT_HISTORY_RESTORE(bm);
1778
1779                 if (!EDBM_op_finish(em, &bmop, op, true)) {
1780                         continue;
1781                 }
1782                 EDBM_update_generic(em, true, true);
1783         }
1784         MEM_freeN(objects);
1785
1786         return OPERATOR_FINISHED;
1787 }
1788
1789 static int edbm_duplicate_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
1790 {
1791         WM_cursor_wait(1);
1792         edbm_duplicate_exec(C, op);
1793         WM_cursor_wait(0);
1794
1795         return OPERATOR_FINISHED;
1796 }
1797
1798 void MESH_OT_duplicate(wmOperatorType *ot)
1799 {
1800         /* identifiers */
1801         ot->name = "Duplicate";
1802         ot->description = "Duplicate selected vertices, edges or faces";
1803         ot->idname = "MESH_OT_duplicate";
1804
1805         /* api callbacks */
1806         ot->invoke = edbm_duplicate_invoke;
1807         ot->exec = edbm_duplicate_exec;
1808
1809         ot->poll = ED_operator_editmesh;
1810
1811         /* to give to transform */
1812         RNA_def_int(ot->srna, "mode", TFM_TRANSLATION, 0, INT_MAX, "Mode", "", 0, INT_MAX);
1813 }
1814
1815 /** \} */
1816
1817 /* -------------------------------------------------------------------- */
1818 /** \name Flip Normals Operator
1819  * \{ */
1820 static int edbm_flip_normals_exec(bContext *C, wmOperator *op)
1821 {
1822         ViewLayer *view_layer = CTX_data_view_layer(C);
1823         uint objects_len = 0;
1824         Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
1825
1826         for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
1827                 Object *obedit = objects[ob_index];
1828                 BMEditMesh *em = BKE_editmesh_from_object(obedit);
1829
1830                 if (em->bm->totfacesel == 0) {
1831                         continue;
1832                 }
1833
1834                 if (!EDBM_op_callf(
1835                         em, op, "reverse_faces faces=%hf flip_multires=%b",
1836                         BM_ELEM_SELECT, true))
1837                 {
1838                         continue;
1839                 }
1840
1841                 EDBM_update_generic(em, true, false);
1842         }
1843
1844         MEM_freeN(objects);
1845         return OPERATOR_FINISHED;
1846 }
1847
1848 void MESH_OT_flip_normals(wmOperatorType *ot)
1849 {
1850         /* identifiers */
1851         ot->name = "Flip Normals";
1852         ot->description = "Flip the direction of selected faces' normals (and of their vertices)";
1853         ot->idname = "MESH_OT_flip_normals";
1854
1855         /* api callbacks */
1856         ot->exec = edbm_flip_normals_exec;
1857         ot->poll = ED_operator_editmesh;
1858
1859         /* flags */
1860         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1861 }
1862
1863 /** \} */
1864
1865 /* -------------------------------------------------------------------- */
1866 /** \name Rotate Edge Operator
1867  * \{ */
1868
1869 /**
1870  * Rotate the edges between selected faces, otherwise rotate the selected edges.
1871  */
1872 static int edbm_edge_rotate_selected_exec(bContext *C, wmOperator *op)
1873 {
1874         BMEdge *eed;
1875         BMIter iter;
1876         const bool use_ccw = RNA_boolean_get(op->ptr, "use_ccw");
1877
1878         int tot_rotate_all = 0, tot_failed_all = 0;
1879         bool no_selected_edges = true, invalid_selected_edges = true;
1880
1881         ViewLayer *view_layer = CTX_data_view_layer(C);
1882         uint objects_len = 0;
1883         Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
1884         for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
1885                 Object *obedit = objects[ob_index];
1886                 BMEditMesh *em = BKE_editmesh_from_object(obedit);
1887                 int tot = 0;
1888
1889                 if (em->bm->totedgesel == 0) {
1890                         continue;
1891                 }
1892                 no_selected_edges = false;
1893
1894                 /* first see if we have two adjacent faces */
1895                 BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
1896                         BM_elem_flag_disable(eed, BM_ELEM_TAG);
1897                         if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
1898                                 BMFace *fa, *fb;
1899                                 if (BM_edge_face_pair(eed, &fa, &fb)) {
1900                                         /* if both faces are selected we rotate between them,
1901                                          * otherwise - rotate between 2 unselected - but not mixed */
1902                                         if (BM_elem_flag_test(fa, BM_ELEM_SELECT) == BM_elem_flag_test(fb, BM_ELEM_SELECT)) {
1903                                                 BM_elem_flag_enable(eed, BM_ELEM_TAG);
1904                                                 tot++;
1905                                         }
1906                                 }
1907                         }
1908                 }
1909
1910                 /* ok, we don't have two adjacent faces, but we do have two selected ones.
1911                  * that's an error condition.*/
1912                 if (tot == 0) {
1913                         continue;
1914                 }
1915                 invalid_selected_edges = false;
1916
1917                 BMOperator bmop;
1918                 EDBM_op_init(em, &bmop, op, "rotate_edges edges=%he use_ccw=%b", BM_ELEM_TAG, use_ccw);
1919
1920                 /* avoids leaving old verts selected which can be a problem running multiple times,
1921                  * since this means the edges become selected around the face which then attempt to rotate */
1922                 BMO_slot_buffer_hflag_disable(em->bm, bmop.slots_in, "edges", BM_EDGE, BM_ELEM_SELECT, true);
1923
1924                 BMO_op_exec(em->bm, &bmop);
1925                 /* edges may rotate into hidden vertices, if this does _not_ run we get an ilogical state */
1926                 BMO_slot_buffer_hflag_disable(em->bm, bmop.slots_out, "edges.out", BM_EDGE, BM_ELEM_HIDDEN, true);
1927                 BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "edges.out", BM_EDGE, BM_ELEM_SELECT, true);
1928
1929                 const int tot_rotate = BMO_slot_buffer_count(bmop.slots_out, "edges.out");
1930                 const int tot_failed = tot - tot_rotate;
1931
1932                 tot_rotate_all += tot_rotate;
1933                 tot_failed_all += tot_failed;
1934
1935                 if (tot_failed != 0) {
1936                         /* If some edges fail to rotate, we need to re-select them,
1937                          * otherwise we can end up with invalid selection
1938                          * (unselected edge between 2 selected faces). */
1939                         BM_mesh_elem_hflag_enable_test(em->bm, BM_EDGE, BM_ELEM_SELECT, true, false, BM_ELEM_TAG);
1940                 }
1941
1942                 EDBM_selectmode_flush(em);
1943
1944                 if (!EDBM_op_finish(em, &bmop, op, true)) {
1945                         continue;
1946                 }
1947
1948                 EDBM_update_generic(em, true, true);
1949         }
1950         MEM_freeN(objects);
1951
1952         if (no_selected_edges) {
1953                 BKE_report(op->reports, RPT_ERROR, "Select edges or face pairs for edge loops to rotate about");
1954                 return OPERATOR_CANCELLED;
1955         }
1956
1957         /* Ok, we don't have two adjacent faces, but we do have two selected ones.
1958          * that's an error condition. */
1959         if (invalid_selected_edges) {
1960                 BKE_report(op->reports, RPT_ERROR, "Could not find any selected edges that can be rotated");
1961                 return OPERATOR_CANCELLED;
1962         }
1963
1964         if (tot_failed_all != 0) {
1965                 BKE_reportf(op->reports, RPT_WARNING, "Unable to rotate %d edge(s)", tot_failed_all);
1966         }
1967
1968         return OPERATOR_FINISHED;
1969 }
1970
1971 void MESH_OT_edge_rotate(wmOperatorType *ot)
1972 {
1973         /* identifiers */
1974         ot->name = "Rotate Selected Edge";
1975         ot->description = "Rotate selected edge or adjoining faces";
1976         ot->idname = "MESH_OT_edge_rotate";
1977
1978         /* api callbacks */
1979         ot->exec = edbm_edge_rotate_selected_exec;
1980         ot->poll = ED_operator_editmesh;
1981
1982         /* flags */
1983         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1984
1985         /* props */
1986         RNA_def_boolean(ot->srna, "use_ccw", false, "Counter Clockwise", "");
1987 }
1988
1989 /** \} */
1990
1991 /* -------------------------------------------------------------------- */
1992 /** \name Hide Operator
1993  * \{ */
1994
1995 static int edbm_hide_exec(bContext *C, wmOperator *op)
1996 {
1997         const bool unselected = RNA_boolean_get(op->ptr, "unselected");
1998         ViewLayer *view_layer = CTX_data_view_layer(C);
1999
2000         uint objects_len = 0;
2001         Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
2002         for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
2003                 Object *obedit = objects[ob_index];
2004                 BMEditMesh *em = BKE_editmesh_from_object(obedit);
2005                 BMesh *bm = em->bm;
2006
2007                 if ((bm->totvertsel == 0) &&
2008                     (bm->totedgesel == 0) &&
2009                     (bm->totfacesel == 0))
2010                 {
2011                         continue;
2012                 }
2013
2014                 EDBM_mesh_hide(em, unselected);
2015                 EDBM_update_generic(em, true, false);
2016         }
2017
2018         MEM_freeN(objects);
2019         return OPERATOR_FINISHED;
2020 }
2021
2022 void MESH_OT_hide(wmOperatorType *ot)
2023 {
2024         /* identifiers */
2025         ot->name = "Hide Selection";
2026         ot->idname = "MESH_OT_hide";
2027         ot->description = "Hide (un)selected vertices, edges or faces";
2028
2029         /* api callbacks */
2030         ot->exec = edbm_hide_exec;
2031         ot->poll = ED_operator_editmesh;
2032
2033         /* flags */
2034         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2035
2036         /* props */
2037         RNA_def_boolean(ot->srna, "unselected", false, "Unselected", "Hide unselected rather than selected");
2038 }
2039
2040 /** \} */
2041
2042 /* -------------------------------------------------------------------- */
2043 /** \name Reveal Operator
2044  * \{ */
2045
2046 static int edbm_reveal_exec(bContext *C, wmOperator *op)
2047 {
2048         const bool select = RNA_boolean_get(op->ptr, "select");
2049         ViewLayer *view_layer = CTX_data_view_layer(C);
2050
2051         uint objects_len = 0;
2052         Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
2053         for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
2054                 Object *obedit = objects[ob_index];
2055                 BMEditMesh *em = BKE_editmesh_from_object(obedit);
2056
2057                 EDBM_mesh_reveal(em, select);
2058                 EDBM_update_generic(em, true, false);
2059         }
2060         MEM_freeN(objects);
2061
2062         return OPERATOR_FINISHED;
2063 }
2064
2065 void MESH_OT_reveal(wmOperatorType *ot)
2066 {
2067         /* identifiers */
2068         ot->name = "Reveal Hidden";
2069         ot->idname = "MESH_OT_reveal";
2070         ot->description = "Reveal all hidden vertices, edges and faces";
2071
2072         /* api callbacks */
2073         ot->exec = edbm_reveal_exec;
2074         ot->poll = ED_operator_editmesh;
2075
2076         /* flags */
2077         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2078
2079         RNA_def_boolean(ot->srna, "select", true, "Select", "");
2080 }
2081
2082 /** \} */
2083
2084 /* -------------------------------------------------------------------- */
2085 /** \name Recalculate Normals Operator
2086  * \{ */
2087
2088 static int edbm_normals_make_consistent_exec(bContext *C, wmOperator *op)
2089 {
2090         ViewLayer *view_layer = CTX_data_view_layer(C);
2091
2092         uint objects_len = 0;
2093         Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
2094         for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
2095                 Object *obedit = objects[ob_index];
2096                 BMEditMesh *em = BKE_editmesh_from_object(obedit);
2097
2098                 if (em->bm->totfacesel == 0) {
2099                         continue;
2100                 }
2101
2102                 if (!EDBM_op_callf(em, op, "recalc_face_normals faces=%hf", BM_ELEM_SELECT)) {
2103                         continue;
2104                 }
2105                 if (RNA_boolean_get(op->ptr, "inside")) {
2106                         EDBM_op_callf(em, op, "reverse_faces faces=%hf flip_multires=%b", BM_ELEM_SELECT, true);
2107                 }
2108
2109                 EDBM_update_generic(em, true, false);
2110         }
2111         MEM_freeN(objects);
2112
2113         return OPERATOR_FINISHED;
2114 }
2115
2116 void MESH_OT_normals_make_consistent(wmOperatorType *ot)
2117 {
2118         /* identifiers */
2119         ot->name = "Make Normals Consistent";
2120         ot->description = "Make face and vertex normals point either outside or inside the mesh";
2121         ot->idname = "MESH_OT_normals_make_consistent";
2122
2123         /* api callbacks */
2124         ot->exec = edbm_normals_make_consistent_exec;
2125         ot->poll = ED_operator_editmesh;
2126
2127         /* flags */
2128         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2129
2130         RNA_def_boolean(ot->srna, "inside", false, "Inside", "");
2131 }
2132
2133 /** \} */
2134
2135 /* -------------------------------------------------------------------- */
2136 /** \name Smooth Vertex Operator
2137  * \{ */
2138
2139 static int edbm_do_smooth_vertex_exec(bContext *C, wmOperator *op)
2140 {
2141         const float fac = RNA_float_get(op->ptr, "factor");
2142
2143         const bool xaxis = RNA_boolean_get(op->ptr, "xaxis");
2144         const bool yaxis = RNA_boolean_get(op->ptr, "yaxis");
2145         const bool zaxis = RNA_boolean_get(op->ptr, "zaxis");
2146         int repeat = RNA_int_get(op->ptr, "repeat");
2147
2148         if (!repeat) {
2149                 repeat = 1;
2150         }
2151
2152         ViewLayer *view_layer = CTX_data_view_layer(C);
2153         uint objects_len = 0;
2154         Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
2155         for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
2156                 Object *obedit = objects[ob_index];
2157                 Mesh *me = obedit->data;
2158                 BMEditMesh *em = BKE_editmesh_from_object(obedit);
2159                 ModifierData *md;
2160                 bool mirrx = false, mirry = false, mirrz = false;
2161                 int i;
2162                 float clip_dist = 0.0f;
2163                 const bool use_topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0;
2164
2165                 if (em->bm->totvertsel == 0) {
2166                         continue;
2167                 }
2168
2169                 /* mirror before smooth */
2170                 if (((Mesh *)obedit->data)->editflag & ME_EDIT_MIRROR_X) {
2171                         EDBM_verts_mirror_cache_begin(em, 0, false, true, use_topology);
2172                 }
2173
2174                 /* if there is a mirror modifier with clipping, flag the verts that
2175                  * are within tolerance of the plane(s) of reflection
2176                  */
2177                 for (md = obedit->modifiers.first; md; md = md->next) {
2178                         if (md->type == eModifierType_Mirror && (md->mode & eModifierMode_Realtime)) {
2179                                 MirrorModifierData *mmd = (MirrorModifierData *)md;
2180
2181                                 if (mmd->flag & MOD_MIR_CLIPPING) {
2182                                         if (mmd->flag & MOD_MIR_AXIS_X)
2183                                                 mirrx = true;
2184                                         if (mmd->flag & MOD_MIR_AXIS_Y)
2185                                                 mirry = true;
2186                                         if (mmd->flag & MOD_MIR_AXIS_Z)
2187                                                 mirrz = true;
2188
2189                                         clip_dist = mmd->tolerance;
2190                                 }
2191                         }
2192                 }
2193
2194                 for (i = 0; i < repeat; i++) {
2195                         if (!EDBM_op_callf(
2196                                 em, op,
2197                                 "smooth_vert verts=%hv factor=%f mirror_clip_x=%b mirror_clip_y=%b mirror_clip_z=%b "
2198                                 "clip_dist=%f use_axis_x=%b use_axis_y=%b use_axis_z=%b",
2199                                 BM_ELEM_SELECT, fac, mirrx, mirry, mirrz, clip_dist, xaxis, yaxis, zaxis))
2200                         {
2201                                 continue;
2202                         }
2203                 }
2204
2205                 /* apply mirror */
2206                 if (((Mesh *)obedit->data)->editflag & ME_EDIT_MIRROR_X) {
2207                         EDBM_verts_mirror_apply(em, BM_ELEM_SELECT, 0);
2208                         EDBM_verts_mirror_cache_end(em);
2209                 }
2210
2211                 EDBM_update_generic(em, true, false);
2212         }
2213         MEM_freeN(objects);
2214
2215         return OPERATOR_FINISHED;
2216 }
2217
2218 void MESH_OT_vertices_smooth(wmOperatorType *ot)
2219 {
2220         /* identifiers */
2221         ot->name = "Smooth Vertex";
2222         ot->description = "Flatten angles of selected vertices";
2223         ot->idname = "MESH_OT_vertices_smooth";
2224
2225         /* api callbacks */
2226         ot->exec = edbm_do_smooth_vertex_exec;
2227         ot->poll = ED_operator_editmesh;
2228
2229         /* flags */
2230         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2231
2232         RNA_def_float(ot->srna, "factor", 0.5f, -10.0f, 10.0f, "Smoothing", "Smoothing factor", 0.0f, 1.0f);
2233         RNA_def_int(ot->srna, "repeat", 1, 1, 1000, "Repeat", "Number of times to smooth the mesh", 1, 100);
2234
2235         WM_operatortype_props_advanced_begin(ot);
2236
2237         RNA_def_boolean(ot->srna, "xaxis", true, "X-Axis", "Smooth along the X axis");
2238         RNA_def_boolean(ot->srna, "yaxis", true, "Y-Axis", "Smooth along the Y axis");
2239         RNA_def_boolean(ot->srna, "zaxis", true, "Z-Axis", "Smooth along the Z axis");
2240 }
2241
2242 /** \} */
2243
2244 /* -------------------------------------------------------------------- */
2245 /** \name Laplacian Vertex Smooth Operator
2246  * \{ */
2247
2248 static int edbm_do_smooth_laplacian_vertex_exec(bContext *C, wmOperator *op)
2249 {
2250         Object *obedit = CTX_data_edit_object(C);
2251         BMEditMesh *em = BKE_editmesh_from_object(obedit);
2252         Mesh *me = obedit->data;
2253         bool use_topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0;
2254         bool usex = true, usey = true, usez = true, preserve_volume = true;
2255         int i, repeat;
2256         float lambda_factor;
2257         float lambda_border;
2258         BMIter fiter;
2259         BMFace *f;
2260
2261         /* Check if select faces are triangles */
2262         BM_ITER_MESH (f, &fiter, em->bm, BM_FACES_OF_MESH) {
2263                 if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
2264                         if (f->len > 4) {
2265                                 BKE_report(op->reports, RPT_WARNING, "Selected faces must be triangles or quads");
2266                                 return OPERATOR_CANCELLED;
2267                         }
2268                 }
2269         }
2270
2271         /* mirror before smooth */
2272         if (((Mesh *)obedit->data)->editflag & ME_EDIT_MIRROR_X) {
2273                 EDBM_verts_mirror_cache_begin(em, 0, false, true, use_topology);
2274         }
2275
2276         repeat = RNA_int_get(op->ptr, "repeat");
2277         lambda_factor = RNA_float_get(op->ptr, "lambda_factor");
2278         lambda_border = RNA_float_get(op->ptr, "lambda_border");
2279         usex = RNA_boolean_get(op->ptr, "use_x");
2280         usey = RNA_boolean_get(op->ptr, "use_y");
2281         usez = RNA_boolean_get(op->ptr, "use_z");
2282         preserve_volume = RNA_boolean_get(op->ptr, "preserve_volume");
2283         if (!repeat)
2284                 repeat = 1;
2285
2286         for (i = 0; i < repeat; i++) {
2287                 if (!EDBM_op_callf(
2288                             em, op,
2289                             "smooth_laplacian_vert verts=%hv lambda_factor=%f lambda_border=%f use_x=%b use_y=%b use_z=%b preserve_volume=%b",
2290                             BM_ELEM_SELECT, lambda_factor, lambda_border, usex, usey, usez, preserve_volume))
2291                 {
2292                         return OPERATOR_CANCELLED;
2293                 }
2294         }
2295
2296         /* apply mirror */
2297         if (((Mesh *)obedit->data)->editflag & ME_EDIT_MIRROR_X) {
2298                 EDBM_verts_mirror_apply(em, BM_ELEM_SELECT, 0);
2299                 EDBM_verts_mirror_cache_end(em);
2300         }
2301
2302         EDBM_update_generic(em, true, false);
2303
2304         return OPERATOR_FINISHED;
2305 }
2306
2307 void MESH_OT_vertices_smooth_laplacian(wmOperatorType *ot)
2308 {
2309         /* identifiers */
2310         ot->name = "Laplacian Smooth Vertex";
2311         ot->description = "Laplacian smooth of selected vertices";
2312         ot->idname = "MESH_OT_vertices_smooth_laplacian";
2313
2314         /* api callbacks */
2315         ot->exec = edbm_do_smooth_laplacian_vertex_exec;
2316         ot->poll = ED_operator_editmesh;
2317
2318         /* flags */
2319         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2320
2321         RNA_def_int(ot->srna, "repeat", 1, 1, 1000,
2322                     "Number of iterations to smooth the mesh", "", 1, 200);
2323         RNA_def_float(ot->srna, "lambda_factor", 1.0f, 1e-7f, 1000.0f,
2324                       "Lambda factor", "", 1e-7f, 1000.0f);
2325         RNA_def_float(ot->srna, "lambda_border", 5e-5f, 1e-7f, 1000.0f,
2326                       "Lambda factor in border", "", 1e-7f, 1000.0f);
2327
2328         WM_operatortype_props_advanced_begin(ot);
2329
2330         RNA_def_boolean(ot->srna, "use_x", true, "Smooth X Axis", "Smooth object along X axis");
2331         RNA_def_boolean(ot->srna, "use_y", true, "Smooth Y Axis", "Smooth object along Y axis");
2332         RNA_def_boolean(ot->srna, "use_z", true, "Smooth Z Axis", "Smooth object along Z axis");
2333         RNA_def_boolean(ot->srna, "preserve_volume", true, "Preserve Volume", "Apply volume preservation after smooth");
2334 }
2335
2336 /** \} */
2337
2338 /* -------------------------------------------------------------------- */
2339 /** \name Set Faces Smooth Shading Operator
2340  * \{ */
2341
2342 static void mesh_set_smooth_faces(BMEditMesh *em, short smooth)
2343 {
2344         BMIter iter;
2345         BMFace *efa;
2346
2347         if (em == NULL) return;
2348
2349         BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
2350                 if (BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
2351                         BM_elem_flag_set(efa, BM_ELEM_SMOOTH, smooth);
2352                 }
2353         }
2354 }
2355
2356 static int edbm_faces_shade_smooth_exec(bContext *C, wmOperator *UNUSED(op))
2357 {
2358         ViewLayer * view_layer = CTX_data_view_layer(C);
2359         uint objects_len = 0;
2360         Object * *objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
2361         for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
2362                 Object * obedit = objects[ob_index];
2363                 BMEditMesh * em = BKE_editmesh_from_object(obedit);
2364
2365                 if (em->bm->totfacesel == 0) {
2366                         continue;
2367                 }
2368
2369                 mesh_set_smooth_faces(em, 1);
2370                 EDBM_update_generic(em, false, false);
2371         }
2372         MEM_freeN(objects);
2373
2374         return OPERATOR_FINISHED;
2375 }
2376
2377 void MESH_OT_faces_shade_smooth(wmOperatorType *ot)
2378 {
2379         /* identifiers */
2380         ot->name = "Shade Smooth";
2381         ot->description = "Display faces smooth (using vertex normals)";
2382         ot->idname = "MESH_OT_faces_shade_smooth";
2383
2384         /* api callbacks */
2385         ot->exec = edbm_faces_shade_smooth_exec;
2386         ot->poll = ED_operator_editmesh;
2387
2388         /* flags */
2389         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2390 }
2391
2392 /** \} */
2393
2394 /* -------------------------------------------------------------------- */
2395 /** \name Set Faces Flat Shading Operator
2396  * \{ */
2397
2398 static int edbm_faces_shade_flat_exec(bContext *C, wmOperator *UNUSED(op))
2399 {
2400         ViewLayer *view_layer = CTX_data_view_layer(C);
2401         uint objects_len = 0;
2402         Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
2403         for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
2404                 Object *obedit = objects[ob_index];
2405                 BMEditMesh *em = BKE_editmesh_from_object(obedit);
2406
2407                 if (em->bm->totfacesel == 0) {
2408                         continue;
2409                 }
2410
2411                 mesh_set_smooth_faces(em, 0);
2412                 EDBM_update_generic(em, false, false);
2413         }
2414         MEM_freeN(objects);
2415
2416         return OPERATOR_FINISHED;
2417 }
2418
2419 void MESH_OT_faces_shade_flat(wmOperatorType *ot)
2420 {
2421         /* identifiers */
2422         ot->name = "Shade Flat";
2423         ot->description = "Display faces flat";
2424         ot->idname = "MESH_OT_faces_shade_flat";
2425
2426         /* api callbacks */
2427         ot->exec = edbm_faces_shade_flat_exec;
2428         ot->poll = ED_operator_editmesh;
2429
2430         /* flags */
2431         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2432 }
2433
2434 /** \} */
2435
2436 /* -------------------------------------------------------------------- */
2437 /** \name UV/Color Rotate/Reverse Operator
2438  * \{ */
2439
2440 static int edbm_rotate_uvs_exec(bContext *C, wmOperator *op)
2441 {
2442         /* get the direction from RNA */
2443         const bool use_ccw = RNA_boolean_get(op->ptr, "use_ccw");
2444
2445         ViewLayer *view_layer = CTX_data_view_layer(C);
2446         uint objects_len = 0;
2447         Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
2448         for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
2449                 Object *obedit = objects[ob_index];
2450                 BMEditMesh *em = BKE_editmesh_from_object(obedit);
2451
2452                 if (em->bm->totfacesel == 0) {
2453                         continue;
2454                 }
2455
2456                 BMOperator bmop;
2457
2458                 /* initialize the bmop using EDBM api, which does various ui error reporting and other stuff */
2459                 EDBM_op_init(em, &bmop, op, "rotate_uvs faces=%hf use_ccw=%b", BM_ELEM_SELECT, use_ccw);
2460
2461                 /* execute the operator */
2462                 BMO_op_exec(em->bm, &bmop);
2463
2464                 if (!EDBM_op_finish(em, &bmop, op, true)) {
2465                         continue;
2466                 }
2467
2468                 EDBM_update_generic(em, false, false);
2469         }
2470
2471         MEM_freeN(objects);
2472         return OPERATOR_FINISHED;
2473 }
2474
2475 static int edbm_reverse_uvs_exec(bContext *C, wmOperator *op)
2476 {
2477         ViewLayer *view_layer = CTX_data_view_layer(C);
2478         uint objects_len = 0;
2479         Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
2480         for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
2481                 Object *obedit = objects[ob_index];
2482                 BMEditMesh *em = BKE_editmesh_from_object(obedit);
2483
2484                 if (em->bm->totfacesel == 0) {
2485                         continue;
2486                 }
2487
2488                 BMOperator bmop;
2489
2490                 /* initialize the bmop using EDBM api, which does various ui error reporting and other stuff */
2491                 EDBM_op_init(em, &bmop, op, "reverse_uvs faces=%hf", BM_ELEM_SELECT);
2492
2493                 /* execute the operator */
2494                 BMO_op_exec(em->bm, &bmop);
2495
2496                 /* finish the operator */
2497                 if (!EDBM_op_finish(em, &bmop, op, true)) {
2498                         continue;
2499                 }
2500                 EDBM_update_generic(em, false, false);
2501         }
2502
2503         MEM_freeN(objects);
2504         return OPERATOR_FINISHED;
2505 }
2506
2507 static int edbm_rotate_colors_exec(bContext *C, wmOperator *op)
2508 {
2509                 /* get the direction from RNA */
2510         const bool use_ccw = RNA_boolean_get(op->ptr, "use_ccw");
2511
2512         ViewLayer *view_layer = CTX_data_view_layer(C);
2513         uint objects_len = 0;
2514         Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
2515
2516         for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
2517                 Object *ob = objects[ob_index];
2518                 BMEditMesh *em = BKE_editmesh_from_object(ob);
2519                 if (em->bm->totfacesel == 0) {
2520                         continue;
2521                 }
2522
2523                 BMOperator bmop;
2524
2525                 /* initialize the bmop using EDBM api, which does various ui error reporting and other stuff */
2526                 EDBM_op_init(em, &bmop, op, "rotate_colors faces=%hf use_ccw=%b", BM_ELEM_SELECT, use_ccw);
2527
2528                 /* execute the operator */
2529                 BMO_op_exec(em->bm, &bmop);
2530
2531                 /* finish the operator */
2532                 if (!EDBM_op_finish(em, &bmop, op, true)) {
2533                         continue;
2534                 }
2535
2536                 /* dependencies graph and notification stuff */
2537                 EDBM_update_generic(em, false, false);
2538         }
2539
2540         MEM_freeN(objects);
2541
2542         return OPERATOR_FINISHED;
2543 }
2544
2545
2546 static int edbm_reverse_colors_exec(bContext *C, wmOperator *op)
2547 {
2548         ViewLayer *view_layer = CTX_data_view_layer(C);
2549         uint objects_len = 0;
2550         Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
2551
2552         for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
2553                 Object *ob = objects[ob_index];
2554                 BMEditMesh *em = BKE_editmesh_from_object(ob);
2555
2556                 if (em->bm->totfacesel == 0) {
2557                         continue;
2558                 }
2559
2560                 BMOperator bmop;
2561
2562                 /* initialize the bmop using EDBM api, which does various ui error reporting and other stuff */
2563                 EDBM_op_init(em, &bmop, op, "reverse_colors faces=%hf", BM_ELEM_SELECT);
2564
2565                 /* execute the operator */
2566                 BMO_op_exec(em->bm, &bmop);
2567
2568                 /* finish the operator */
2569                 if (!EDBM_op_finish(em, &bmop, op, true)) {
2570                         return OPERATOR_CANCELLED;
2571                 }
2572
2573                 EDBM_update_generic(em, false, false);
2574         }
2575         MEM_freeN(objects);
2576
2577         return OPERATOR_FINISHED;
2578 }
2579
2580 void MESH_OT_uvs_rotate(wmOperatorType *ot)
2581 {
2582         /* identifiers */
2583         ot->name = "Rotate UVs";
2584         ot->idname = "MESH_OT_uvs_rotate";
2585         ot->description = "Rotate UV coordinates inside faces";
2586
2587         /* api callbacks */
2588         ot->exec = edbm_rotate_uvs_exec;
2589         ot->poll = ED_operator_editmesh;
2590
2591         /* flags */
2592         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2593
2594         /* props */
2595         RNA_def_boolean(ot->srna, "use_ccw", false, "Counter Clockwise", "");
2596 }
2597
2598 void MESH_OT_uvs_reverse(wmOperatorType *ot)
2599 {
2600         /* identifiers */
2601         ot->name = "Reverse UVs";
2602         ot->idname = "MESH_OT_uvs_reverse";
2603         ot->description = "Flip direction of UV coordinates inside faces";
2604
2605         /* api callbacks */
2606         ot->exec = edbm_reverse_uvs_exec;
2607         ot->poll = ED_operator_editmesh;
2608
2609         /* flags */
2610         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2611
2612         /* props */
2613         //RNA_def_enum(ot->srna, "axis", axis_items, DIRECTION_CW, "Axis", "Axis to mirror UVs around");
2614 }
2615
2616 void MESH_OT_colors_rotate(wmOperatorType *ot)
2617 {
2618         /* identifiers */
2619         ot->name = "Rotate Colors";
2620         ot->idname = "MESH_OT_colors_rotate";
2621         ot->description = "Rotate vertex colors inside faces";
2622
2623         /* api callbacks */
2624         ot->exec = edbm_rotate_colors_exec;
2625         ot->poll = ED_operator_editmesh;
2626
2627         /* flags */
2628         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2629
2630         /* props */
2631         RNA_def_boolean(ot->srna, "use_ccw", false, "Counter Clockwise", "");
2632 }
2633
2634 void MESH_OT_colors_reverse(wmOperatorType *ot)
2635 {
2636         /* identifiers */
2637         ot->name = "Reverse Colors";
2638         ot->idname = "MESH_OT_colors_reverse";
2639         ot->description = "Flip direction of vertex colors inside faces";
2640
2641         /* api callbacks */
2642         ot->exec = edbm_reverse_colors_exec;
2643         ot->poll = ED_operator_editmesh;
2644
2645         /* flags */
2646         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2647
2648         /* props */
2649         //RNA_def_enum(ot->srna, "axis", axis_items, DIRECTION_CW, "Axis", "Axis to mirror colors around");
2650 }
2651
2652 /** \} */
2653
2654 /* -------------------------------------------------------------------- */
2655 /** \name Merge Vertices Operator
2656  * \{ */
2657
2658 enum {
2659         MESH_MERGE_LAST     = 1,
2660         MESH_MERGE_CENTER   = 3,
2661         MESH_MERGE_CURSOR   = 4,
2662         MESH_MERGE_COLLAPSE = 5,
2663         MESH_MERGE_FIRST    = 6,
2664 };
2665
2666 static bool merge_firstlast(BMEditMesh *em, const bool use_first, const bool use_uvmerge, wmOperator *wmop)
2667 {
2668         BMVert *mergevert;
2669         BMEditSelection *ese;
2670
2671         /* operator could be called directly from shortcut or python,
2672          * so do extra check for data here
2673          */
2674
2675         /* do sanity check in mergemenu in edit.c ?*/
2676         if (use_first == false) {
2677                 if (!em->bm->selected.last || ((BMEditSelection *)em->bm->selected.last)->htype != BM_VERT)
2678                         return false;
2679
2680                 ese = em->bm->selected.last;
2681                 mergevert = (BMVert *)ese->ele;
2682         }
2683         else {
2684                 if (!em->bm->selected.first || ((BMEditSelection *)em->bm->selected.first)->htype != BM_VERT)
2685                         return false;
2686
2687                 ese = em->bm->selected.first;
2688                 mergevert = (BMVert *)ese->ele;
2689         }
2690
2691         if (!BM_elem_flag_test(mergevert, BM_ELEM_SELECT))
2692                 return false;
2693
2694         if (use_uvmerge) {
2695                 if (!EDBM_op_callf(em, wmop, "pointmerge_facedata verts=%hv vert_snap=%e", BM_ELEM_SELECT, mergevert))
2696                         return false;
2697         }
2698
2699         if (!EDBM_op_callf(em, wmop, "pointmerge verts=%hv merge_co=%v", BM_ELEM_SELECT, mergevert->co))
2700                 return false;
2701
2702         return true;
2703 }
2704
2705 static bool merge_target(
2706         BMEditMesh *em, Scene *scene, View3D *v3d, Object *ob,
2707         const bool use_cursor, const bool use_uvmerge, wmOperator *wmop)
2708 {
2709         BMIter iter;
2710         BMVert *v;
2711         float co[3], cent[3] = {0.0f, 0.0f, 0.0f};
2712         const float *vco = NULL;
2713
2714         if (use_cursor) {
2715                 vco = ED_view3d_cursor3d_get(scene, v3d)->location;
2716                 copy_v3_v3(co, vco);
2717                 invert_m4_m4(ob->imat, ob->obmat);
2718                 mul_m4_v3(ob->imat, co);
2719         }
2720         else {
2721                 float fac;
2722                 int i = 0;
2723                 BM_ITER_MESH (v, &iter, em->bm, BM_VERTS_OF_MESH) {
2724                         if (!BM_elem_flag_test(v, BM_ELEM_SELECT))
2725                                 continue;
2726                         add_v3_v3(cent, v->co);
2727                         i++;
2728                 }
2729
2730                 if (!i)
2731                         return false;
2732
2733                 fac = 1.0f / (float)i;
2734                 mul_v3_fl(cent, fac);
2735                 copy_v3_v3(co, cent);
2736                 vco = co;
2737         }
2738
2739         if (!vco)
2740                 return false;
2741
2742         if (use_uvmerge) {
2743                 if (!EDBM_op_callf(em, wmop, "average_vert_facedata verts=%hv", BM_ELEM_SELECT))
2744                         return false;
2745         }
2746
2747         if (!EDBM_op_callf(em, wmop, "pointmerge verts=%hv merge_co=%v", BM_ELEM_SELECT, co))
2748                 return false;
2749
2750         return true;
2751 }
2752
2753 static int edbm_merge_exec(bContext *C, wmOperator *op)
2754 {
2755         Scene *scene = CTX_data_scene(C);
2756         View3D *v3d = CTX_wm_view3d(C);
2757         ViewLayer *view_layer = CTX_data_view_layer(C);
2758         uint objects_len = 0;
2759         Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
2760         const int type = RNA_enum_get(op->ptr, "type");
2761         const bool uvs = RNA_boolean_get(op->ptr, "uvs");
2762
2763         for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
2764                 Object *obedit = objects[ob_index];
2765                 BMEditMesh *em = BKE_editmesh_from_object(obedit);
2766
2767                 if (em->bm->totvertsel == 0) {
2768                         continue;
2769                 }
2770
2771                 bool ok = false;
2772                 switch (type) {
2773                         case MESH_MERGE_CENTER:
2774                                 ok = merge_target(em, scene, v3d, obedit, false, uvs, op);
2775                                 break;
2776                         case MESH_MERGE_CURSOR:
2777                                 ok = merge_target(em, scene, v3d, obedit, true, uvs, op);
2778                                 break;
2779                         case MESH_MERGE_LAST:
2780                                 ok = merge_firstlast(em, false, uvs, op);
2781                                 break;
2782                         case MESH_MERGE_FIRST:
2783                                 ok = merge_firstlast(em, true, uvs, op);
2784                                 break;
2785                         case MESH_MERGE_COLLAPSE:
2786                                 ok = EDBM_op_callf(em, op, "collapse edges=%he uvs=%b", BM_ELEM_SELECT, uvs);
2787                                 break;
2788                         default:
2789                                 BLI_assert(0);
2790                                 break;
2791                 }
2792
2793                 if (!ok) {
2794                         continue;
2795                 }
2796
2797                 EDBM_update_generic(em, true, true);
2798
2799                 /* once collapsed, we can't have edge/face selection */
2800                 if ((em->selectmode & SCE_SELECT_VERTEX) == 0) {
2801                         EDBM_flag_disable_all(em, BM_ELEM_SELECT);
2802                 }
2803                 /* Only active object supported, see comment below. */
2804                 if (ELEM(type, MESH_MERGE_FIRST, MESH_MERGE_LAST)) {
2805                         break;
2806                 }
2807         }
2808
2809         MEM_freeN(objects);
2810
2811         return OPERATOR_FINISHED;
2812 }
2813
2814 static const EnumPropertyItem merge_type_items[] = {
2815         {MESH_MERGE_FIRST, "FIRST", 0, "At First", ""},
2816         {MESH_MERGE_LAST, "LAST", 0, "At Last", ""},
2817         {MESH_MERGE_CENTER, "CENTER", 0, "At Center", ""},
2818         {MESH_MERGE_CURSOR, "CURSOR", 0, "At Cursor", ""},
2819         {MESH_MERGE_COLLAPSE, "COLLAPSE", 0, "Collapse", ""},
2820         {0, NULL, 0, NULL, NULL}
2821 };
2822
2823 static const EnumPropertyItem *merge_type_itemf(bContext *C, PointerRNA *UNUSED(ptr),  PropertyRNA *UNUSED(prop), bool *r_free)
2824 {
2825         Object *obedit;
2826         EnumPropertyItem *item = NULL;
2827         int totitem = 0;
2828
2829         if (!C) /* needed for docs */
2830                 return merge_type_items;
2831
2832         obedit = CTX_data_edit_object(C);
2833         if (obedit && obedit->type == OB_MESH) {
2834                 BMEditMesh *em = BKE_editmesh_from_object(obedit);
2835
2836                 /* Only active object supported:
2837                  * In practice it doesn't make sense to run this operation on non-active meshes
2838                  * since selecting will activate - we could have own code-path for these but it's a hassle
2839                  * for now just apply to the active (first) object. */
2840                 if (em->selectmode & SCE_SELECT_VERTEX) {
2841                         if (em->bm->selected.first && em->bm->selected.last &&
2842                             ((BMEditSelection *)em->bm->selected.first)->htype == BM_VERT &&
2843                             ((BMEditSelection *)em->bm->selected.last)->htype == BM_VERT)
2844                         {
2845                                 RNA_enum_items_add_value(&item, &totitem, merge_type_items, MESH_MERGE_FIRST);
2846                                 RNA_enum_items_add_value(&item, &totitem, merge_type_items, MESH_MERGE_LAST);
2847                         }
2848                         else if (em->bm->selected.first && ((BMEditSelection *)em->bm->selected.first)->htype == BM_VERT) {
2849                                 RNA_enum_items_add_value(&item, &totitem, merge_type_items, MESH_MERGE_FIRST);
2850                         }
2851                         else if (em->bm->selected.last && ((BMEditSelection *)em->bm->selected.last)->htype == BM_VERT) {
2852                                 RNA_enum_items_add_value(&item, &totitem, merge_type_items, MESH_MERGE_LAST);
2853                         }
2854                 }
2855
2856                 RNA_enum_items_add_value(&item, &totitem, merge_type_items, MESH_MERGE_CENTER);
2857                 RNA_enum_items_add_value(&item, &totitem, merge_type_items, MESH_MERGE_CURSOR);
2858                 RNA_enum_items_add_value(&item, &totitem, merge_type_items, MESH_MERGE_COLLAPSE);
2859                 RNA_enum_item_end(&item, &totitem);
2860
2861                 *r_free = true;
2862
2863                 return item;
2864         }
2865
2866         return NULL;
2867 }
2868
2869 void MESH_OT_merge(wmOperatorType *ot)
2870 {
2871         /* identifiers */
2872         ot->name = "Merge";
2873         ot->description = "Merge selected vertices";
2874         ot->idname = "MESH_OT_merge";
2875
2876         /* api callbacks */
2877         ot->exec = edbm_merge_exec;
2878         ot->invoke = WM_menu_invoke;
2879         ot->poll = ED_operator_editmesh;
2880
2881         /* flags */
2882         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2883
2884         /* properties */
2885         ot->prop = RNA_def_enum(ot->srna, "type", merge_type_items, MESH_MERGE_CENTER, "Type", "Merge method to use");
2886         RNA_def_enum_funcs(ot->prop, merge_type_itemf);
2887
2888         WM_operatortype_props_advanced_begin(ot);
2889
2890         RNA_def_boolean(ot->srna, "uvs", false, "UVs", "Move UVs according to merge");
2891 }
2892
2893 /** \} */
2894
2895 /* -------------------------------------------------------------------- */
2896 /** \name Remove Doubles Operator
2897  * \{ */
2898
2899 static int edbm_remove_doubles_exec(bContext *C, wmOperator *op)
2900 {
2901         const float threshold = RNA_float_get(op->ptr, "threshold");
2902         const bool use_unselected = RNA_boolean_get(op->ptr, "use_unselected");
2903         int count_multi = 0;
2904
2905         ViewLayer *view_layer = CTX_data_view_layer(C);
2906         uint objects_len = 0;
2907         Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
2908
2909         for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
2910                 Object *obedit = objects[ob_index];
2911                 BMEditMesh *em = BKE_editmesh_from_object(obedit);
2912
2913                 /* Selection used as target with 'use_unselected'. */
2914                 if (em->bm->totvertsel == 0) {
2915                         continue;
2916                 }
2917
2918                 BMOperator bmop;
2919                 const int totvert_orig = em->bm->totvert;
2920
2921                 /* avoid loosing selection state (select -> tags) */
2922                 char htype_select;
2923                 if      (em->selectmode & SCE_SELECT_VERTEX) htype_select = BM_VERT;
2924                 else if (em->selectmode & SCE_SELECT_EDGE)   htype_select = BM_EDGE;
2925                 else                                         htype_select = BM_FACE;
2926
2927                 /* store selection as tags */
2928                 BM_mesh_elem_hflag_enable_test(em->bm, htype_select, BM_ELEM_TAG, true, true, BM_ELEM_SELECT);
2929
2930
2931                 if (use_unselected) {
2932                         EDBM_op_init(
2933                                 em, &bmop, op,
2934                                 "automerge verts=%hv dist=%f",
2935                                 BM_ELEM_SELECT, threshold);
2936                         BMO_op_exec(em->bm, &bmop);
2937
2938                         if (!EDBM_op_finish(em, &bmop, op, true)) {
2939                                 continue;
2940                         }
2941                 }
2942                 else {
2943                         EDBM_op_init(
2944                                 em, &bmop, op,
2945                                 "find_doubles verts=%hv dist=%f",
2946                                 BM_ELEM_SELECT, threshold);
2947
2948                         BMO_op_exec(em->bm, &bmop);
2949
2950                         if (!EDBM_op_callf(em, op, "weld_verts targetmap=%S", &bmop, "targetmap.out")) {
2951                                 BMO_op_finish(em->bm, &bmop);
2952                                 continue;
2953                         }
2954
2955                         if (!EDBM_op_finish(em, &bmop, op, true)) {
2956                                 continue;
2957                         }
2958                 }
2959
2960                 const int count = (totvert_orig - em->bm->totvert);
2961
2962                 /* restore selection from tags */
2963                 BM_mesh_elem_hflag_enable_test(em->bm, htype_select, BM_ELEM_SELECT, true, true, BM_ELEM_TAG);
2964                 EDBM_selectmode_flush(em);
2965
2966                 if (count) {
2967                         count_multi += count;
2968                         EDBM_update_generic(em, true, true);
2969                 }
2970         }
2971         MEM_freeN(objects);
2972
2973         BKE_reportf(op->reports, RPT_INFO, "Removed %d vertices", count_multi);
2974
2975         return OPERATOR_FINISHED;
2976 }
2977
2978 void MESH_OT_remove_doubles(wmOperatorType *ot)
2979 {
2980         /* identifiers */
2981         ot->name = "Remove Doubles";
2982         ot->description = "Remove duplicate vertices";
2983         ot->idname = "MESH_OT_remove_doubles";
2984
2985         /* api callbacks */
2986         ot->exec = edbm_remove_doubles_exec;
2987         ot->poll = ED_operator_editmesh;
2988
2989         /* flags */
2990         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2991
2992         RNA_def_float_distance(ot->srna, "threshold", 1e-4f, 1e-6f, 50.0f, "Merge Distance",
2993                                "Minimum distance between elements to merge", 1e-5f, 10.0f);
2994         RNA_def_boolean(ot->srna, "use_unselected", false, "Unselected", "Merge selected to other unselected vertices");
2995 }
2996
2997 /** \} */
2998
2999 /* -------------------------------------------------------------------- */
3000 /** \name Shape Key Propagate Operator
3001  * \{ */
3002
3003 /* BMESH_TODO this should be properly encapsulated in a bmop.  but later.*/
3004 static void shape_propagate(BMEditMesh *em, wmOperator *op)
3005 {
3006         BMIter iter;
3007         BMVert *eve = NULL;
3008         float *co;
3009         int i, totshape = CustomData_number_of_layers(&em->bm->vdata, CD_SHAPEKEY);
3010
3011         if (!CustomData_has_layer(&em->bm->vdata, CD_SHAPEKEY)) {
3012                 BKE_report(op->reports, RPT_ERROR, "Mesh does not have shape keys");
3013                 return;
3014         }
3015
3016         BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
3017                 if (!BM_elem_flag_test(eve, BM_ELEM_SELECT) || BM_elem_flag_test(eve, BM_ELEM_HIDDEN))
3018                         continue;
3019
3020                 for (i = 0; i < totshape; i++) {
3021                         co = CustomData_bmesh_get_n(&em->bm->vdata, eve->head.data, CD_SHAPEKEY, i);
3022                         copy_v3_v3(co, eve->co);
3023                 }
3024         }
3025
3026 #if 0
3027         //TAG Mesh Objects that share this data
3028         for (base = scene->base.first; base; base = base->next) {
3029                 if (base->object && base->object->data == me) {
3030                         DEG_id_tag_update(&base->object->id, OB_RECALC_DATA);
3031                 }
3032         }
3033 #endif
3034 }
3035
3036
3037 static int edbm_shape_propagate_to_all_exec(bContext *C, wmOperator *op)
3038 {
3039         Object *obedit = CTX_data_edit_object(C);
3040         Mesh *me = obedit->data;
3041         BMEditMesh *em = me->edit_btmesh;
3042
3043         shape_propagate(em, op);
3044
3045         EDBM_update_generic(em, false, false);
3046
3047         return OPERATOR_FINISHED;
3048 }
3049
3050
3051 void MESH_OT_shape_propagate_to_all(wmOperatorType *ot)
3052 {
3053         /* identifiers */
3054         ot->name = "Shape Propagate";
3055         ot->description = "Apply selected vertex locations to all other shape keys";
3056         ot->idname = "MESH_OT_shape_propagate_to_all";
3057
3058         /* api callbacks */
3059         ot->exec = edbm_shape_propagate_to_all_exec;
3060         ot->poll = ED_operator_editmesh;
3061
3062         /* flags */
3063         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
3064 }
3065
3066 /** \} */
3067
3068 /* -------------------------------------------------------------------- */
3069 /** \name Blend from Shape Operator
3070  * \{ */
3071
3072 /* BMESH_TODO this should be properly encapsulated in a bmop.  but later.*/
3073 static int edbm_blend_from_shape_exec(bContext *C, wmOperator *op)
3074 {
3075         Object *obedit = CTX_data_edit_object(C);
3076         Mesh *me = obedit->data;
3077         Key *key = me->key;
3078         KeyBlock *kb = NULL;
3079         BMEditMesh *em = me->edit_btmesh;
3080         BMVert *eve;
3081         BMIter iter;
3082         float co[3], *sco;
3083         int totshape;
3084
3085         const float blend = RNA_float_get(op->ptr, "blend");
3086         const int shape = RNA_enum_get(op->ptr, "shape");
3087         const bool use_add = RNA_boolean_get(op->ptr, "add");
3088
3089         /* sanity check */
3090         totshape = CustomData_number_of_layers(&em->bm->vdata, CD_SHAPEKEY);
3091         if (totshape == 0 || shape < 0 || shape >= totshape)
3092                 return OPERATOR_CANCELLED;
3093
3094         /* get shape key - needed for finding reference shape (for add mode only) */
3095         if (key) {
3096                 kb = BLI_findlink(&key->block, shape);
3097         }
3098
3099         /* perform blending on selected vertices*/
3100         BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
3101                 if (!BM_elem_flag_test(eve, BM_ELEM_SELECT) || BM_elem_flag_test(eve, BM_ELEM_HIDDEN))
3102                         continue;
3103
3104                 /* get coordinates of shapekey we're blending from */
3105                 sco = CustomData_bmesh_get_n(&em->bm->vdata, eve->head.data, CD_SHAPEKEY, shape);
3106                 copy_v3_v3(co, sco);
3107
3108                 if (use_add) {
3109                         /* in add mode, we add relative shape key offset */
3110                         if (kb) {
3111                                 const float *rco = CustomData_bmesh_get_n(&em->bm->vdata, eve->head.data, CD_SHAPEKEY, kb->relative);
3112                                 sub_v3_v3v3(co, co, rco);
3113                         }
3114
3115                         madd_v3_v3fl(eve->co, co, blend);
3116                 }
3117                 else {
3118                         /* in blend mode, we interpolate to the shape key */
3119                         interp_v3_v3v3(eve->co, eve->co, co, blend);
3120                 }
3121         }
3122
3123         EDBM_update_generic(em, true, false);
3124
3125         return OPERATOR_FINISHED;
3126 }
3127
3128 static const EnumPropertyItem *shape_itemf(bContext *C, PointerRNA *UNUSED(ptr),  PropertyRNA *UNUSED(prop), bool *r_free)
3129 {
3130         Object *obedit = CTX_data_edit_object(C);
3131         BMEditMesh *em;
3132         EnumPropertyItem *item = NULL;
3133         int totitem = 0;
3134
3135         if ((obedit && obedit->type == OB_MESH) &&
3136             (em = BKE_editmesh_from_object(obedit)) &&
3137             CustomData_has_layer(&em->bm->vdata, CD_SHAPEKEY))
3138         {
3139                 EnumPropertyItem tmp = {0, "", 0, "", ""};
3140                 int a;
3141
3142                 for (a = 0; a < em->bm->vdata.totlayer; a++) {
3143                         if (em->bm->vdata.layers[a].type != CD_SHAPEKEY)
3144                                 continue;
3145
3146                         tmp.value = totitem;
3147                         tmp.identifier = em->bm->vdata.layers[a].name;
3148                         tmp.name = em->bm->vdata.layers[a].name;
3149                         /* RNA_enum_item_add sets totitem itself! */
3150                         RNA_enum_item_add(&item, &totitem, &tmp);
3151                 }
3152         }
3153
3154         RNA_enum_item_end(&item, &totitem);
3155         *r_free = true;
3156
3157         return item;
3158 }
3159
3160 static void edbm_blend_from_shape_ui(bContext *C, wmOperator *op)
3161 {
3162         uiLayout *layout = op->layout;
3163         PointerRNA ptr;
3164         Object *obedit = CTX_data_edit_object(C);
3165         Mesh *me = obedit->data;
3166         PointerRNA ptr_key;
3167
3168         RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr);
3169         RNA_id_pointer_create((ID *)me->key, &ptr_key);
3170
3171         uiItemPointerR(layout, &ptr, "shape", &ptr_key, "key_blocks", "", ICON_SHAPEKEY_DATA);
3172         uiItemR(layout, &ptr, "blend", 0, NULL, ICON_NONE);
3173         uiItemR(layout, &ptr, "add", 0, NULL, ICON_NONE);
3174 }
3175
3176 void MESH_OT_blend_from_shape(wmOperatorType *ot)
3177 {
3178         PropertyRNA *prop;
3179
3180         /* identifiers */
3181         ot->name = "Blend From Shape";
3182         ot->description = "Blend in shape from a shape key";
3183         ot->idname = "MESH_OT_blend_from_shape";
3184
3185         /* api callbacks */
3186         ot->exec = edbm_blend_from_shape_exec;
3187 //      ot->invoke = WM_operator_props_popup_call;  /* disable because search popup closes too easily */
3188         ot->ui = edbm_blend_from_shape_ui;
3189         ot->poll = ED_operator_editmesh;
3190
3191         /* flags */
3192         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
3193
3194         /* properties */
3195         prop = RNA_def_enum(ot->srna, "shape", DummyRNA_NULL_items, 0, "Shape", "Shape key to use for blending");
3196         RNA_def_enum_funcs(prop, shape_itemf);
3197         RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE | PROP_NEVER_UNLINK);
3198         RNA_def_float(ot->srna, "blend", 1.0f, -1e3f, 1e3f, "Blend", "Blending factor", -2.0f, 2.0f);
3199         RNA_def_boolean(ot->srna, "add", true, "Add", "Add rather than blend between shapes");
3200 }
3201
3202 /** \} */
3203
3204 /* -------------------------------------------------------------------- */
3205 /** \name Solidify Mesh Operator
3206  * \{ */
3207
3208 static int edbm_solidify_exec(bContext *C, wmOperator *op)
3209 {
3210         const float thickness = RNA_float_get(op->ptr, "thickness");
3211
3212         ViewLayer *view_layer = CTX_data_view_layer(C);
3213         uint objects_len = 0;
3214         Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
3215         for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
3216                 Object *obedit = objects[ob_index];
3217                 BMEditMesh *em = BKE_editmesh_from_object(obedit);
3218                 BMesh *bm = em->bm;
3219
3220                 if (em->bm->totfacesel == 0) {
3221                         continue;
3222                 }
3223
3224                 BMOperator bmop;
3225
3226                 if (!EDBM_op_init(em, &bmop, op, "solidify geom=%hf thickness=%f", BM_ELEM_SELECT, thickness)) {
3227                         continue;
3228                 }
3229
3230                 /* deselect only the faces in the region to be solidified (leave wire
3231                  * edges and loose verts selected, as there will be no corresponding
3232                  * geometry selected below) */
3233                 BMO_slot_buffer_hflag_disable(bm, bmop.slots_in, "geom", BM_FACE, BM_ELEM_SELECT, true);
3234
3235                 /* run the solidify operator */
3236                 BMO_op_exec(bm, &bmop);
3237
3238                 /* select the newly generated faces */
3239                 BMO_slot_buffer_hflag_enable(bm, bmop.slots_out, "geom.out", BM_FACE, BM_ELEM_SELECT, true);
3240
3241                 if (!EDBM_op_finish(em, &bmop, op, true)) {
3242                         continue;
3243                 }
3244
3245                 EDBM_update_generic(em, true, true);
3246         }
3247
3248         MEM_freeN(objects);
3249         return OPERATOR_FINISHED;
3250 }
3251
3252 void MESH_OT_solidify(wmOperatorType *ot)
3253 {
3254         PropertyRNA *prop;
3255         /* identifiers */
3256         ot->name = "Solidify";
3257         ot->description = "Create a solid skin by extruding, compensating for sharp angles";
3258         ot->idname = "MESH_OT_solidify";
3259
3260         /* api callbacks&n