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