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