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