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