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