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