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