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