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