Fix T58113 Multiple problems with bevel harden normals.
[blender.git] / source / blender / bmesh / intern / bmesh_opdefines.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  * Contributor(s): Joseph Eagar, Geoffrey Bantle, Campbell Barton
19  *
20  * ***** END GPL LICENSE BLOCK *****
21  */
22
23 /** \file blender/bmesh/intern/bmesh_opdefines.c
24  *  \ingroup bmesh
25  *
26  * BMesh operator definitions.
27  *
28  * This file defines (and documents) all bmesh operators (bmops).
29  *
30  * Do not rename any operator or slot names! otherwise you must go
31  * through the code and find all references to them!
32  *
33  * A word on slot names:
34  *
35  * For geometry input slots, the following are valid names:
36  * - verts
37  * - edges
38  * - faces
39  * - edgefacein
40  * - vertfacein
41  * - vertedgein
42  * - vertfacein
43  * - geom
44  *
45  * The basic rules are, for single-type geometry slots, use the plural of the
46  * type name (e.g. edges).  for double-type slots, use the two type names plus
47  * "in" (e.g. edgefacein).  for three-type slots, use geom.
48  *
49  * for output slots, for single-type geometry slots, use the type name plus "out",
50  * (e.g. verts.out), for double-type slots, use the two type names plus "out",
51  * (e.g. vertfaces.out), for three-type slots, use geom.  note that you can also
52  * use more esoteric names (e.g. geom_skirt.out) so long as the comment next to the
53  * slot definition tells you what types of elements are in it.
54  *
55  */
56
57 #include "BLI_utildefines.h"
58
59 #include "bmesh.h"
60 #include "intern/bmesh_operators_private.h"
61
62 #include "DNA_modifier_types.h"
63
64 /* The formatting of these bmesh operators is parsed by
65  * 'doc/python_api/rst_from_bmesh_opdefines.py'
66  * for use in python docs, so reStructuredText may be used
67  * rather then doxygen syntax.
68  *
69  * template (py quotes used because nested comments don't work
70  * on all C compilers):
71  *
72  * """
73  * Region Extend.
74  *
75  * paragraph1, Extends bleh bleh bleh.
76  * Bleh Bleh bleh.
77  *
78  * Another paragraph.
79  *
80  * Another paragraph.
81  * """
82  *
83  * so the first line is the "title" of the bmop.
84  * subsequent line blocks separated by blank lines
85  * are paragraphs.  individual descriptions of slots
86  * are extracted from comments next to them.
87  *
88  * eg:
89  *     {BMO_OP_SLOT_ELEMENT_BUF, "geom.out"},  """ output slot, boundary region """
90  *
91  * ... or:
92  *
93  * """ output slot, boundary region """
94  *     {BMO_OP_SLOT_ELEMENT_BUF, "geom.out"},
95  *
96  * Both are acceptable.
97  * note that '//' comments are ignored.
98  */
99
100 /* enums shared between multiple operators */
101
102 static BMO_FlagSet bmo_enum_axis_xyz[] = {
103         {0, "X"},
104         {1, "Y"},
105         {2, "Z"},
106         {0, NULL},
107 };
108
109 static BMO_FlagSet bmo_enum_falloff_type[] = {
110         {SUBD_FALLOFF_SMOOTH, "SMOOTH"},
111         {SUBD_FALLOFF_SPHERE, "SPHERE"},
112         {SUBD_FALLOFF_ROOT, "ROOT"},
113         {SUBD_FALLOFF_SHARP, "SHARP"},
114         {SUBD_FALLOFF_LIN, "LINEAR"},
115         {SUBD_FALLOFF_INVSQUARE, "INVERSE_SQUARE"},
116         {0, NULL},
117 };
118
119 /*
120  * Vertex Smooth.
121  *
122  * Smooths vertices by using a basic vertex averaging scheme.
123  */
124 static BMOpDefine bmo_smooth_vert_def = {
125         "smooth_vert",
126         /* slots_in */
127         {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},    /* input vertices */
128          {"factor", BMO_OP_SLOT_FLT},           /* smoothing factor */
129          {"mirror_clip_x", BMO_OP_SLOT_BOOL},   /* set vertices close to the x axis before the operation to 0 */
130          {"mirror_clip_y", BMO_OP_SLOT_BOOL},   /* set vertices close to the y axis before the operation to 0 */
131          {"mirror_clip_z", BMO_OP_SLOT_BOOL},   /* set vertices close to the z axis before the operation to 0 */
132          {"clip_dist",  BMO_OP_SLOT_FLT},       /* clipping threshold for the above three slots */
133          {"use_axis_x", BMO_OP_SLOT_BOOL},      /* smooth vertices along X axis */
134          {"use_axis_y", BMO_OP_SLOT_BOOL},      /* smooth vertices along Y axis */
135          {"use_axis_z", BMO_OP_SLOT_BOOL},      /* smooth vertices along Z axis */
136          {{'\0'}},
137         },
138         {{{'\0'}}},  /* no output */
139         bmo_smooth_vert_exec,
140         (BMO_OPTYPE_FLAG_NORMALS_CALC),
141 };
142
143 /*
144  * Vertex Smooth Laplacian.
145  *
146  * Smooths vertices by using Laplacian smoothing propose by.
147  * Desbrun, et al. Implicit Fairing of Irregular Meshes using Diffusion and Curvature Flow.
148  */
149 static BMOpDefine bmo_smooth_laplacian_vert_def = {
150         "smooth_laplacian_vert",
151         /* slots_in */
152         {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},    /* input vertices */
153          {"lambda_factor", BMO_OP_SLOT_FLT},           /* lambda param */
154          {"lambda_border", BMO_OP_SLOT_FLT},    /* lambda param in border */
155          {"use_x", BMO_OP_SLOT_BOOL},           /* Smooth object along X axis */
156          {"use_y", BMO_OP_SLOT_BOOL},           /* Smooth object along Y axis */
157          {"use_z", BMO_OP_SLOT_BOOL},           /* Smooth object along Z axis */
158          {"preserve_volume", BMO_OP_SLOT_BOOL}, /* Apply volume preservation after smooth */
159          {{'\0'}},
160         },
161         {{{'\0'}}},  /* no output */
162         bmo_smooth_laplacian_vert_exec,
163         (BMO_OPTYPE_FLAG_NORMALS_CALC),
164 };
165
166 /*
167  * Right-Hand Faces.
168  *
169  * Computes an "outside" normal for the specified input faces.
170  */
171 static BMOpDefine bmo_recalc_face_normals_def = {
172         "recalc_face_normals",
173         /* slots_in */
174         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
175          {{'\0'}},
176         },
177         {{{'\0'}}},  /* no output */
178         bmo_recalc_face_normals_exec,
179         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
180          BMO_OPTYPE_FLAG_NORMALS_CALC),
181 };
182
183 /*
184  * Planar Faces.
185  *
186  * Iteratively flatten faces.
187  */
188 static BMOpDefine bmo_planar_faces_def = {
189         "planar_faces",
190         /* slots_in */
191         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},    /* input geometry. */
192          {"iterations", BMO_OP_SLOT_INT},  /* Number of times to flatten faces (for when connected faces are used) */
193          {"factor", BMO_OP_SLOT_FLT},  /* Influence for making planar each iteration */
194          {{'\0'}},
195         },
196         /* slots_out */
197         {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* output slot, computed boundary geometry. */
198          {{'\0'}},
199         },
200         bmo_planar_faces_exec,
201         (BMO_OPTYPE_FLAG_SELECT_FLUSH |
202          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
203 };
204
205 /*
206  * Region Extend.
207  *
208  * used to implement the select more/less tools.
209  * this puts some geometry surrounding regions of
210  * geometry in geom into geom.out.
211  *
212  * if use_faces is 0 then geom.out spits out verts and edges,
213  * otherwise it spits out faces.
214  */
215 static BMOpDefine bmo_region_extend_def = {
216         "region_extend",
217         /* slots_in */
218         {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},     /* input geometry */
219          {"use_contract", BMO_OP_SLOT_BOOL},    /* find boundary inside the regions, not outside. */
220          {"use_faces", BMO_OP_SLOT_BOOL},       /* extend from faces instead of edges */
221          {"use_face_step", BMO_OP_SLOT_BOOL},   /* step over connected faces */
222          {{'\0'}},
223         },
224         /* slots_out */
225         {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* output slot, computed boundary geometry. */
226          {{'\0'}},
227         },
228         bmo_region_extend_exec,
229         (BMO_OPTYPE_FLAG_SELECT_FLUSH |
230          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
231 };
232
233 /*
234  * Edge Rotate.
235  *
236  * Rotates edges topologically.  Also known as "spin edge" to some people.
237  * Simple example: ``[/] becomes [|] then [\]``.
238  */
239 static BMOpDefine bmo_rotate_edges_def = {
240         "rotate_edges",
241         /* slots_in */
242         {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},    /* input edges */
243          {"use_ccw", BMO_OP_SLOT_BOOL},         /* rotate edge counter-clockwise if true, otherwise clockwise */
244          {{'\0'}},
245         },
246         /* slots_out */
247         {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* newly spun edges */
248          {{'\0'}},
249         },
250         bmo_rotate_edges_exec,
251         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
252          BMO_OPTYPE_FLAG_NORMALS_CALC |
253          BMO_OPTYPE_FLAG_SELECT_FLUSH |
254          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
255 };
256
257 /*
258  * Reverse Faces.
259  *
260  * Reverses the winding (vertex order) of faces.
261  * This has the effect of flipping the normal.
262  */
263 static BMOpDefine bmo_reverse_faces_def = {
264         "reverse_faces",
265         /* slots_in */
266         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},    /* input faces */
267          {"flip_multires", BMO_OP_SLOT_BOOL},  /* maintain multi-res offset */
268          {{'\0'}},
269         },
270         {{{'\0'}}},  /* no output */
271         bmo_reverse_faces_exec,
272         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
273          BMO_OPTYPE_FLAG_NORMALS_CALC),
274 };
275
276 /*
277  * Edge Bisect.
278  *
279  * Splits input edges (but doesn't do anything else).
280  * This creates a 2-valence vert.
281  */
282 static BMOpDefine bmo_bisect_edges_def = {
283         "bisect_edges",
284         /* slots_in */
285         {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
286          {"cuts", BMO_OP_SLOT_INT}, /* number of cuts */
287          {"edge_percents", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_FLT}},
288          {{'\0'}},
289         },
290         /* slots_out */
291         {{"geom_split.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* newly created vertices and edges */
292          {{'\0'}},
293         },
294         bmo_bisect_edges_exec,
295         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
296          BMO_OPTYPE_FLAG_NORMALS_CALC |
297          BMO_OPTYPE_FLAG_SELECT_FLUSH |
298          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
299 };
300
301 /*
302  * Mirror.
303  *
304  * Mirrors geometry along an axis.  The resulting geometry is welded on using
305  * merge_dist.  Pairs of original/mirrored vertices are welded using the merge_dist
306  * parameter (which defines the minimum distance for welding to happen).
307  */
308 static BMOpDefine bmo_mirror_def = {
309         "mirror",
310         /* slots_in */
311         {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},     /* input geometry */
312          {"matrix",          BMO_OP_SLOT_MAT},   /* matrix defining the mirror transformation */
313          {"merge_dist",      BMO_OP_SLOT_FLT},   /* maximum distance for merging.  does no merging if 0. */
314          {"axis",            BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, bmo_enum_axis_xyz},   /* the axis to use. */
315          {"mirror_u",        BMO_OP_SLOT_BOOL},  /* mirror UVs across the u axis */
316          {"mirror_v",        BMO_OP_SLOT_BOOL},  /* mirror UVs across the v axis */
317          {{'\0'}},
318         },
319         /* slots_out */
320         {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* output geometry, mirrored */
321          {{'\0'}},
322         },
323         bmo_mirror_exec,
324         (BMO_OPTYPE_FLAG_NORMALS_CALC |
325          BMO_OPTYPE_FLAG_SELECT_FLUSH |
326          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
327 };
328
329 /*
330  * Find Doubles.
331  *
332  * Takes input verts and find vertices they should weld to.
333  * Outputs a mapping slot suitable for use with the weld verts bmop.
334  *
335  * If keep_verts is used, vertices outside that set can only be merged
336  * with vertices in that set.
337  */
338 static BMOpDefine bmo_find_doubles_def = {
339         "find_doubles",
340         /* slots_in */
341         {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
342          {"keep_verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* list of verts to keep */
343          {"dist",         BMO_OP_SLOT_FLT}, /* minimum distance */
344          {{'\0'}},
345         },
346         /* slots_out */
347         {{"targetmap.out", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
348          {{'\0'}},
349         },
350         bmo_find_doubles_exec,
351         (BMO_OPTYPE_FLAG_NOP),
352 };
353
354 /*
355  * Remove Doubles.
356  *
357  * Finds groups of vertices closer then dist and merges them together,
358  * using the weld verts bmop.
359  */
360 static BMOpDefine bmo_remove_doubles_def = {
361         "remove_doubles",
362         /* slots_in */
363         {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input verts */
364          {"dist",         BMO_OP_SLOT_FLT}, /* minimum distance */
365          {{'\0'}},
366         },
367         {{{'\0'}}},  /* no output */
368         bmo_remove_doubles_exec,
369         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
370          BMO_OPTYPE_FLAG_NORMALS_CALC |
371          BMO_OPTYPE_FLAG_SELECT_FLUSH |
372          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
373 };
374
375 /*
376  * Auto Merge.
377  *
378  * Finds groups of vertices closer then **dist** and merges them together,
379  * using the weld verts bmop.  The merges must go from a vert not in
380  * **verts** to one in **verts**.
381  */
382 static BMOpDefine bmo_automerge_def = {
383         "automerge",
384         /* slots_in */
385         {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input verts */
386          {"dist",         BMO_OP_SLOT_FLT}, /* minimum distance */
387          {{'\0'}},
388         },
389         {{{'\0'}}},  /* no output */
390         bmo_automerge_exec,
391         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
392          BMO_OPTYPE_FLAG_NORMALS_CALC |
393          BMO_OPTYPE_FLAG_SELECT_FLUSH |
394          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
395 };
396
397 /*
398  * Collapse Connected.
399  *
400  * Collapses connected vertices
401  */
402 static BMOpDefine bmo_collapse_def = {
403         "collapse",
404         /* slots_in */
405         {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
406          {"uvs", BMO_OP_SLOT_BOOL}, /* also collapse UVs and such */
407          {{'\0'}},
408         },
409         {{{'\0'}}},  /* no output */
410         bmo_collapse_exec,
411         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
412          BMO_OPTYPE_FLAG_NORMALS_CALC |
413          BMO_OPTYPE_FLAG_SELECT_FLUSH |
414          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
415 };
416
417 /*
418  * Face-Data Point Merge.
419  *
420  * Merge uv/vcols at a specific vertex.
421  */
422 static BMOpDefine bmo_pointmerge_facedata_def = {
423         "pointmerge_facedata",
424         /* slots_in */
425         {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},    /* input vertices */
426          {"vert_snap", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | (int)BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE}},    /* snap vertex */
427          {{'\0'}},
428         },
429         {{{'\0'}}},  /* no output */
430         bmo_pointmerge_facedata_exec,
431         (BMO_OPTYPE_FLAG_NOP),
432 };
433
434 /*
435  * Average Vertices Facevert Data.
436  *
437  * Merge uv/vcols associated with the input vertices at
438  * the bounding box center. (I know, it's not averaging but
439  * the vert_snap_to_bb_center is just too long).
440  */
441 static BMOpDefine bmo_average_vert_facedata_def = {
442         "average_vert_facedata",
443         /* slots_in */
444         {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
445          {{'\0'}},
446         },
447         {{{'\0'}}},  /* no output */
448         bmo_average_vert_facedata_exec,
449         (BMO_OPTYPE_FLAG_NOP),
450 };
451
452 /*
453  * Point Merge.
454  *
455  * Merge verts together at a point.
456  */
457 static BMOpDefine bmo_pointmerge_def = {
458         "pointmerge",
459         /* slots_in */
460         {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices (all verts will be merged into the first). */
461          {"merge_co", BMO_OP_SLOT_VEC},  /* Position to merge at. */
462          {{'\0'}},
463         },
464         {{{'\0'}}},  /* no output */
465         bmo_pointmerge_exec,
466         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
467          BMO_OPTYPE_FLAG_NORMALS_CALC |
468          BMO_OPTYPE_FLAG_SELECT_FLUSH |
469          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
470 };
471
472 /*
473  * Collapse Connected UV's.
474  *
475  * Collapses connected UV vertices.
476  */
477 static BMOpDefine bmo_collapse_uvs_def = {
478         "collapse_uvs",
479         /* slots_in */
480         {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
481          {{'\0'}},
482         },
483         {{{'\0'}}},  /* no output */
484         bmo_collapse_uvs_exec,
485         (BMO_OPTYPE_FLAG_NOP),
486 };
487
488 /*
489  * Weld Verts.
490  *
491  * Welds verts together (kind-of like remove doubles, merge, etc, all of which
492  * use or will use this bmop).  You pass in mappings from vertices to the vertices
493  * they weld with.
494  */
495 static BMOpDefine bmo_weld_verts_def = {
496         "weld_verts",
497         /* slots_in */
498         /* maps welded vertices to verts they should weld to */
499         {{"targetmap", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
500          {{'\0'}},
501         },
502         {{{'\0'}}},  /* no output */
503         bmo_weld_verts_exec,
504         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
505          BMO_OPTYPE_FLAG_NORMALS_CALC |
506          BMO_OPTYPE_FLAG_SELECT_FLUSH |
507          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
508 };
509
510 /*
511  * Make Vertex.
512  *
513  * Creates a single vertex; this bmop was necessary
514  * for click-create-vertex.
515  */
516 static BMOpDefine bmo_create_vert_def = {
517         "create_vert",
518         /* slots_in */
519         {{"co", BMO_OP_SLOT_VEC},  /* the coordinate of the new vert */
520          {{'\0'}},
521         },
522         /* slots_out */
523         {{"vert.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},  /* the new vert */
524          {{'\0'}},
525         },
526         bmo_create_vert_exec,
527         (BMO_OPTYPE_FLAG_NOP),
528 };
529
530 /*
531  * Join Triangles.
532  *
533  * Tries to intelligently join triangles according
534  * to angle threshold and delimiters.
535  */
536 static BMOpDefine bmo_join_triangles_def = {
537         "join_triangles",
538         /* slots_in */
539         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},    /* input geometry. */
540          {"cmp_seam", BMO_OP_SLOT_BOOL},
541          {"cmp_sharp", BMO_OP_SLOT_BOOL},
542          {"cmp_uvs", BMO_OP_SLOT_BOOL},
543          {"cmp_vcols", BMO_OP_SLOT_BOOL},
544          {"cmp_materials", BMO_OP_SLOT_BOOL},
545          {"angle_face_threshold", BMO_OP_SLOT_FLT},
546          {"angle_shape_threshold", BMO_OP_SLOT_FLT},
547          {{'\0'}},
548         },
549         /* slots_out */
550         {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},  /* joined faces */
551          {{'\0'}},
552         },
553         bmo_join_triangles_exec,
554         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
555          BMO_OPTYPE_FLAG_NORMALS_CALC |
556          BMO_OPTYPE_FLAG_SELECT_FLUSH |
557          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
558 };
559
560 /*
561  * Contextual Create.
562  *
563  * This is basically F-key, it creates
564  * new faces from vertices, makes stuff from edge nets,
565  * makes wire edges, etc.  It also dissolves faces.
566  *
567  * Three verts become a triangle, four become a quad.  Two
568  * become a wire edge.
569  */
570 static BMOpDefine bmo_contextual_create_def = {
571         "contextual_create",
572         /* slots_in */
573         {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},     /* input geometry. */
574          {"mat_nr",         BMO_OP_SLOT_INT},   /* material to use */
575          {"use_smooth",        BMO_OP_SLOT_BOOL}, /* smooth to use */
576          {{'\0'}},
577         },
578         /* slots_out */
579         {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* newly-made face(s) */
580         /* note, this is for stand-alone edges only, not edges which are apart of newly created faces */
581          {"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* newly-made edge(s) */
582          {{'\0'}},
583         },
584         bmo_contextual_create_exec,
585         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
586          BMO_OPTYPE_FLAG_NORMALS_CALC |
587          BMO_OPTYPE_FLAG_SELECT_FLUSH |
588          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
589 };
590
591 /*
592  * Bridge edge loops with faces.
593  */
594 static BMOpDefine bmo_bridge_loops_def = {
595         "bridge_loops",
596         /* slots_in */
597         {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
598          {"use_pairs",          BMO_OP_SLOT_BOOL},
599          {"use_cyclic",         BMO_OP_SLOT_BOOL},
600          {"use_merge",          BMO_OP_SLOT_BOOL},
601          {"merge_factor",       BMO_OP_SLOT_FLT},
602          {"twist_offset",       BMO_OP_SLOT_INT},
603          {{'\0'}},
604         },
605         /* slots_out */
606         {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* new faces */
607          {"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* new edges */
608          {{'\0'}},
609         },
610         bmo_bridge_loops_exec,
611         (BMO_OPTYPE_FLAG_NORMALS_CALC |
612          BMO_OPTYPE_FLAG_SELECT_FLUSH |
613          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
614 };
615
616 /*
617  * Grid Fill.
618  *
619  * Create faces defined by 2 disconnected edge loops (which share edges).
620  */
621 static BMOpDefine bmo_grid_fill_def = {
622         "grid_fill",
623         /* slots_in */
624         {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
625         /* restricts edges to groups.  maps edges to integer */
626          {"mat_nr",         BMO_OP_SLOT_INT},      /* material to use */
627          {"use_smooth",     BMO_OP_SLOT_BOOL},     /* smooth state to use */
628          {"use_interp_simple", BMO_OP_SLOT_BOOL},  /* use simple interpolation */
629          {{'\0'}},
630         },
631         /* slots_out */
632         /* maps new faces to the group numbers they came from */
633         {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},     /* new faces */
634          {{'\0'}},
635         },
636         bmo_grid_fill_exec,
637         (BMO_OPTYPE_FLAG_NORMALS_CALC |
638          BMO_OPTYPE_FLAG_SELECT_FLUSH),
639 };
640
641
642 /*
643  * Fill Holes.
644  *
645  * Fill boundary edges with faces, copying surrounding customdata.
646  */
647 static BMOpDefine bmo_holes_fill_def = {
648         "holes_fill",
649         /* slots_in */
650         {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
651          {"sides",          BMO_OP_SLOT_INT},   /* number of face sides to fill */
652          {{'\0'}},
653         },
654         /* slots_out */
655         /* maps new faces to the group numbers they came from */
656         {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},     /* new faces */
657          {{'\0'}},
658         },
659         bmo_holes_fill_exec,
660         (BMO_OPTYPE_FLAG_NORMALS_CALC |
661          BMO_OPTYPE_FLAG_SELECT_FLUSH),
662 };
663
664
665 /*
666  * Face Attribute Fill.
667  *
668  * Fill in faces with data from adjacent faces.
669  */
670 static BMOpDefine bmo_face_attribute_fill_def = {
671         "face_attribute_fill",
672         /* slots_in */
673         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},     /* input faces */
674          {"use_normals",        BMO_OP_SLOT_BOOL},  /* copy face winding */
675          {"use_data",           BMO_OP_SLOT_BOOL},  /* copy face data */
676          {{'\0'}},
677         },
678         /* slots_out */
679         /* maps new faces to the group numbers they came from */
680         {{"faces_fail.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},     /* faces that could not be handled */
681          {{'\0'}},
682         },
683         bmo_face_attribute_fill_exec,
684         (BMO_OPTYPE_FLAG_NORMALS_CALC),
685 };
686
687 /*
688  * Edge Loop Fill.
689  *
690  * Create faces defined by one or more non overlapping edge loops.
691  */
692 static BMOpDefine bmo_edgeloop_fill_def = {
693         "edgeloop_fill",
694         /* slots_in */
695         {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
696         /* restricts edges to groups.  maps edges to integer */
697          {"mat_nr",         BMO_OP_SLOT_INT},      /* material to use */
698          {"use_smooth",        BMO_OP_SLOT_BOOL},  /* smooth state to use */
699          {{'\0'}},
700         },
701         /* slots_out */
702         /* maps new faces to the group numbers they came from */
703         {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},     /* new faces */
704          {{'\0'}},
705         },
706         bmo_edgeloop_fill_exec,
707         (BMO_OPTYPE_FLAG_NORMALS_CALC |
708          BMO_OPTYPE_FLAG_SELECT_FLUSH),
709 };
710
711
712 /*
713  * Edge Net Fill.
714  *
715  * Create faces defined by enclosed edges.
716  */
717 static BMOpDefine bmo_edgenet_fill_def = {
718         "edgenet_fill",
719         /* slots_in */
720         {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
721          {"mat_nr",          BMO_OP_SLOT_INT},  /* material to use */
722          {"use_smooth",      BMO_OP_SLOT_BOOL}, /* smooth state to use */
723          {"sides",           BMO_OP_SLOT_INT},  /* number of sides */
724          {{'\0'}},
725         },
726         /* slots_out */
727         /* maps new faces to the group numbers they came from */
728         {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},  /* new faces */
729          {{'\0'}},
730         },
731         bmo_edgenet_fill_exec,
732         (BMO_OPTYPE_FLAG_NORMALS_CALC |
733          BMO_OPTYPE_FLAG_SELECT_FLUSH),
734 };
735
736 /*
737  * Edgenet Prepare.
738  *
739  * Identifies several useful edge loop cases and modifies them so
740  * they'll become a face when edgenet_fill is called.  The cases covered are:
741  *
742  * - One single loop; an edge is added to connect the ends
743  * - Two loops; two edges are added to connect the endpoints (based on the
744  *   shortest distance between each endpont).
745  */
746 static BMOpDefine bmo_edgenet_prepare_def = {
747         "edgenet_prepare",
748         /* slots_in */
749         {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},    /* input edges */
750          {{'\0'}},
751         },
752         /* slots_out */
753         {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},  /* new edges */
754          {{'\0'}},
755         },
756         bmo_edgenet_prepare_exec,
757         (BMO_OPTYPE_FLAG_NOP),
758 };
759
760 /*
761  * Rotate.
762  *
763  * Rotate vertices around a center, using a 3x3 rotation matrix.
764  */
765 static BMOpDefine bmo_rotate_def = {
766         "rotate",
767         /* slots_in */
768         {{"cent",            BMO_OP_SLOT_VEC},  /* center of rotation */
769          {"matrix",          BMO_OP_SLOT_MAT},  /* matrix defining rotation */
770          {"verts",           BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},  /* input vertices */
771          {"space",           BMO_OP_SLOT_MAT},  /* matrix to define the space (typically object matrix) */
772          {{'\0'}},
773         },
774         {{{'\0'}}},  /* no output */
775         bmo_rotate_exec,
776         (BMO_OPTYPE_FLAG_NORMALS_CALC),
777 };
778
779 /*
780  * Translate.
781  *
782  * Translate vertices by an offset.
783  */
784 static BMOpDefine bmo_translate_def = {
785         "translate",
786         /* slots_in */
787         {{"vec", BMO_OP_SLOT_VEC},  /* translation offset */
788          {"space", BMO_OP_SLOT_MAT},  /* matrix to define the space (typically object matrix) */
789          {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},  /* input vertices */
790          {{'\0'}},
791         },
792         {{{'\0'}}},  /* no output */
793         bmo_translate_exec,
794         (BMO_OPTYPE_FLAG_NORMALS_CALC),
795 };
796
797 /*
798  * Scale.
799  *
800  * Scales vertices by an offset.
801  */
802 static BMOpDefine bmo_scale_def = {
803         "scale",
804         /* slots_in */
805         {{"vec", BMO_OP_SLOT_VEC},  /* scale factor */
806          {"space", BMO_OP_SLOT_MAT},  /* matrix to define the space (typically object matrix) */
807          {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},  /* input vertices */
808          {{'\0'}},
809         },
810         {{{'\0'}}},  /* no output */
811         bmo_scale_exec,
812         (BMO_OPTYPE_FLAG_NORMALS_CALC),
813 };
814
815
816 /*
817  * Transform.
818  *
819  * Transforms a set of vertices by a matrix.  Multiplies
820  * the vertex coordinates with the matrix.
821  */
822 static BMOpDefine bmo_transform_def = {
823         "transform",
824         /* slots_in */
825         {{"matrix",          BMO_OP_SLOT_MAT},  /* transform matrix */
826          {"space",           BMO_OP_SLOT_MAT},  /* matrix to define the space (typically object matrix) */
827          {"verts",           BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},  /* input vertices */
828          {{'\0'}},
829         },
830         {{{'\0'}}},  /* no output */
831         bmo_transform_exec,
832         (BMO_OPTYPE_FLAG_NORMALS_CALC),
833 };
834
835 /*
836  * Object Load BMesh.
837  *
838  * Loads a bmesh into an object/mesh.  This is a "private"
839  * bmop.
840  */
841 static BMOpDefine bmo_object_load_bmesh_def = {
842         "object_load_bmesh",
843         /* slots_in */
844         {{"scene", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_SCENE}},
845          {"object", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_OBJECT}},
846          {{'\0'}},
847         },
848         {{{'\0'}}},  /* no output */
849         bmo_object_load_bmesh_exec,
850         (BMO_OPTYPE_FLAG_NOP),
851 };
852
853
854 /*
855  * BMesh to Mesh.
856  *
857  * Converts a bmesh to a Mesh.  This is reserved for exiting editmode.
858  */
859 static BMOpDefine bmo_bmesh_to_mesh_def = {
860         "bmesh_to_mesh",
861         /* slots_in */
862         {
863          /* pointer to a mesh structure to fill in */
864          {"mesh", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_MESH}},
865         /* pointer to an object structure */
866          {"object", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_OBJECT}},
867          {{'\0'}},
868         },
869         {{{'\0'}}},  /* no output */
870         bmo_bmesh_to_mesh_exec,
871         (BMO_OPTYPE_FLAG_NOP),
872 };
873
874 /*
875  * Mesh to BMesh.
876  *
877  * Load the contents of a mesh into the bmesh.  this bmop is private, it's
878  * reserved exclusively for entering editmode.
879  */
880 static BMOpDefine bmo_mesh_to_bmesh_def = {
881         "mesh_to_bmesh",
882         /* slots_in */
883         {
884          /* pointer to a Mesh structure */
885          {"mesh", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_MESH}},
886         /* pointer to an Object structure */
887          {"object", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_OBJECT}},
888          {"use_shapekey", BMO_OP_SLOT_BOOL},  /* load active shapekey coordinates into verts */
889          {{'\0'}},
890         },
891         {{{'\0'}}},  /* no output */
892         bmo_mesh_to_bmesh_exec,
893         (BMO_OPTYPE_FLAG_NOP),
894 };
895
896 /*
897  * Individual Face Extrude.
898  *
899  * Extrudes faces individually.
900  */
901 static BMOpDefine bmo_extrude_discrete_faces_def = {
902         "extrude_discrete_faces",
903         /* slots_in */
904         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},     /* input faces */
905          {"use_normal_flip", BMO_OP_SLOT_BOOL},  /* Create faces with reversed direction. */
906          {"use_select_history", BMO_OP_SLOT_BOOL},  /* pass to duplicate */
907          {{'\0'}},
908         },
909         /* slots_out */
910         {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},   /* output faces */
911          {{'\0'}},
912         },
913         bmo_extrude_discrete_faces_exec,
914         (BMO_OPTYPE_FLAG_NORMALS_CALC),
915 };
916
917 /*
918  * Extrude Only Edges.
919  *
920  * Extrudes Edges into faces, note that this is very simple, there's no fancy
921  * winged extrusion.
922  */
923 static BMOpDefine bmo_extrude_edge_only_def = {
924         "extrude_edge_only",
925         /* slots_in */
926         {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},    /* input vertices */
927          {"use_normal_flip", BMO_OP_SLOT_BOOL},  /* Create faces with reversed direction. */
928          {"use_select_history", BMO_OP_SLOT_BOOL},  /* pass to duplicate */
929          {{'\0'}},
930         },
931         /* slots_out */
932         {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},  /* output geometry */
933          {{'\0'}},
934         },
935         bmo_extrude_edge_only_exec,
936         (BMO_OPTYPE_FLAG_NORMALS_CALC),
937 };
938
939 /*
940  * Individual Vertex Extrude.
941  *
942  * Extrudes wire edges from vertices.
943  */
944 static BMOpDefine bmo_extrude_vert_indiv_def = {
945         "extrude_vert_indiv",
946         /* slots_in */
947         {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},    /* input vertices */
948          {"use_select_history", BMO_OP_SLOT_BOOL},  /* pass to duplicate */
949          {{'\0'}},
950         },
951         /* slots_out */
952         {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},  /* output wire edges */
953          {"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},  /* output vertices */
954          {{'\0'}},
955         },
956         bmo_extrude_vert_indiv_exec,
957         (BMO_OPTYPE_FLAG_SELECT_FLUSH),
958 };
959
960 /*
961  * Connect Verts.
962  *
963  * Split faces by adding edges that connect **verts**.
964  */
965 static BMOpDefine bmo_connect_verts_def = {
966         "connect_verts",
967         /* slots_in */
968         {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},
969          {"faces_exclude", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
970          {"check_degenerate", BMO_OP_SLOT_BOOL},  /* prevent splits with overlaps & intersections */
971          {{'\0'}},
972         },
973         /* slots_out */
974         {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
975          {{'\0'}},
976         },
977         bmo_connect_verts_exec,
978         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
979          BMO_OPTYPE_FLAG_NORMALS_CALC |
980          BMO_OPTYPE_FLAG_SELECT_FLUSH),
981 };
982
983 /*
984  * Connect Verts to form Convex Faces.
985  *
986  * Ensures all faces are convex **faces**.
987  */
988 static BMOpDefine bmo_connect_verts_concave_def = {
989         "connect_verts_concave",
990         /* slots_in */
991         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
992          {{'\0'}},
993         },
994         /* slots_out */
995         {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
996          {"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
997          {{'\0'}},
998         },
999         bmo_connect_verts_concave_exec,
1000         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
1001          BMO_OPTYPE_FLAG_NORMALS_CALC |
1002          BMO_OPTYPE_FLAG_SELECT_FLUSH),
1003 };
1004
1005 /*
1006  * Connect Verts Across non Planer Faces.
1007  *
1008  * Split faces by connecting edges along non planer **faces**.
1009  */
1010 static BMOpDefine bmo_connect_verts_nonplanar_def = {
1011         "connect_verts_nonplanar",
1012         /* slots_in */
1013         {{"angle_limit", BMO_OP_SLOT_FLT}, /* total rotation angle (radians) */
1014          {"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
1015          {{'\0'}},
1016         },
1017         /* slots_out */
1018         {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
1019          {"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
1020          {{'\0'}},
1021         },
1022         bmo_connect_verts_nonplanar_exec,
1023         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
1024          BMO_OPTYPE_FLAG_NORMALS_CALC |
1025          BMO_OPTYPE_FLAG_SELECT_FLUSH),
1026 };
1027
1028 /*
1029  * Connect Verts.
1030  *
1031  * Split faces by adding edges that connect **verts**.
1032  */
1033 static BMOpDefine bmo_connect_vert_pair_def = {
1034         "connect_vert_pair",
1035         /* slots_in */
1036         {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},
1037          {"verts_exclude", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},
1038          {"faces_exclude", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
1039          {{'\0'}},
1040         },
1041         /* slots_out */
1042         {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
1043          {{'\0'}},
1044         },
1045         bmo_connect_vert_pair_exec,
1046         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
1047          BMO_OPTYPE_FLAG_NORMALS_CALC |
1048          BMO_OPTYPE_FLAG_SELECT_FLUSH),
1049 };
1050
1051
1052 /*
1053  * Extrude Faces.
1054  *
1055  * Extrude operator (does not transform)
1056  */
1057 static BMOpDefine bmo_extrude_face_region_def = {
1058         "extrude_face_region",
1059         /* slots_in */
1060         {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},     /* edges and faces */
1061          {"edges_exclude", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_EMPTY}},
1062          {"use_keep_orig", BMO_OP_SLOT_BOOL},   /* keep original geometry (requires ``geom`` to include edges). */
1063          {"use_normal_flip", BMO_OP_SLOT_BOOL},  /* Create faces with reversed direction. */
1064          {"use_select_history", BMO_OP_SLOT_BOOL},  /* pass to duplicate */
1065          {{'\0'}},
1066         },
1067         /* slots_out */
1068         {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1069          {{'\0'}},
1070         },
1071         bmo_extrude_face_region_exec,
1072         (BMO_OPTYPE_FLAG_NORMALS_CALC),
1073 };
1074
1075 /*
1076  * Dissolve Verts.
1077  */
1078 static BMOpDefine bmo_dissolve_verts_def = {
1079         "dissolve_verts",
1080         /* slots_in */
1081         {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},
1082          {"use_face_split", BMO_OP_SLOT_BOOL},
1083          {"use_boundary_tear", BMO_OP_SLOT_BOOL},
1084          {{'\0'}},
1085         },
1086         {{{'\0'}}},  /* no output */
1087         bmo_dissolve_verts_exec,
1088         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
1089          BMO_OPTYPE_FLAG_NORMALS_CALC |
1090          BMO_OPTYPE_FLAG_SELECT_FLUSH |
1091          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
1092 };
1093
1094 /*
1095  * Dissolve Edges.
1096  */
1097 static BMOpDefine bmo_dissolve_edges_def = {
1098         "dissolve_edges",
1099         /* slots_in */
1100         {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
1101          {"use_verts", BMO_OP_SLOT_BOOL},  /* dissolve verts left between only 2 edges. */
1102          {"use_face_split", BMO_OP_SLOT_BOOL},
1103          {{'\0'}},
1104         },
1105         /* slots_out */
1106         {{"region.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
1107          {{'\0'}},
1108         },
1109         bmo_dissolve_edges_exec,
1110         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
1111          BMO_OPTYPE_FLAG_NORMALS_CALC |
1112          BMO_OPTYPE_FLAG_SELECT_FLUSH |
1113          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
1114 };
1115
1116 /*
1117  * Dissolve Faces.
1118  */
1119 static BMOpDefine bmo_dissolve_faces_def = {
1120         "dissolve_faces",
1121         /* slots_in */
1122         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
1123          {"use_verts", BMO_OP_SLOT_BOOL},  /* dissolve verts left between only 2 edges. */
1124          {{'\0'}},
1125         },
1126         /* slots_out */
1127         {{"region.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
1128          {{'\0'}},
1129         },
1130         bmo_dissolve_faces_exec,
1131         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
1132          BMO_OPTYPE_FLAG_NORMALS_CALC |
1133          BMO_OPTYPE_FLAG_SELECT_FLUSH |
1134          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
1135 };
1136
1137 static BMO_FlagSet bmo_enum_dissolve_limit_flags[] = {
1138         {BMO_DELIM_NORMAL, "NORMAL"},
1139         {BMO_DELIM_MATERIAL, "MATERIAL"},
1140         {BMO_DELIM_SEAM, "SEAM"},
1141         {BMO_DELIM_SHARP, "SHARP"},
1142         {BMO_DELIM_UV, "UV"},
1143         {0, NULL}
1144 };
1145
1146 /*
1147  * Limited Dissolve.
1148  *
1149  * Dissolve planar faces and co-linear edges.
1150  */
1151 static BMOpDefine bmo_dissolve_limit_def = {
1152         "dissolve_limit",
1153         /* slots_in */
1154         {{"angle_limit", BMO_OP_SLOT_FLT}, /* total rotation angle (radians) */
1155          {"use_dissolve_boundaries", BMO_OP_SLOT_BOOL},
1156          {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},
1157          {"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
1158          {"delimit", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_FLAG}, bmo_enum_dissolve_limit_flags},
1159          {{'\0'}},
1160         },
1161         /* slots_out */
1162         {{"region.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
1163          {{'\0'}}},
1164         bmo_dissolve_limit_exec,
1165         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
1166          BMO_OPTYPE_FLAG_NORMALS_CALC |
1167          BMO_OPTYPE_FLAG_SELECT_FLUSH |
1168          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
1169 };
1170
1171 /*
1172  * Degenerate Dissolve.
1173  *
1174  * Dissolve edges with no length, faces with no area.
1175  */
1176 static BMOpDefine bmo_dissolve_degenerate_def = {
1177         "dissolve_degenerate",
1178         /* slots_in */
1179         {{"dist", BMO_OP_SLOT_FLT}, /* minimum distance to consider degenerate */
1180          {"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
1181          {{'\0'}},
1182         },
1183         /* slots_out */
1184         {{{'\0'}}},
1185         bmo_dissolve_degenerate_exec,
1186         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
1187          BMO_OPTYPE_FLAG_NORMALS_CALC |
1188          BMO_OPTYPE_FLAG_SELECT_FLUSH |
1189          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
1190 };
1191
1192 static BMO_FlagSet bmo_enum_triangulate_quad_method[] = {
1193         {MOD_TRIANGULATE_QUAD_BEAUTY, "BEAUTY"},
1194         {MOD_TRIANGULATE_QUAD_FIXED, "FIXED"},
1195         {MOD_TRIANGULATE_QUAD_ALTERNATE, "ALTERNATE"},
1196         {MOD_TRIANGULATE_QUAD_SHORTEDGE, "SHORT_EDGE"},
1197         {0, NULL},
1198 };
1199
1200 static BMO_FlagSet bmo_enum_triangulate_ngon_method[] = {
1201         {MOD_TRIANGULATE_NGON_BEAUTY, "BEAUTY"},
1202         {MOD_TRIANGULATE_NGON_EARCLIP, "EAR_CLIP"},
1203         {0, NULL},
1204 };
1205
1206 /*
1207  * Triangulate.
1208  */
1209 static BMOpDefine bmo_triangulate_def = {
1210         "triangulate",
1211         /* slots_in */
1212         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
1213          {"quad_method", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, bmo_enum_triangulate_quad_method},
1214          {"ngon_method", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, bmo_enum_triangulate_ngon_method},
1215          {{'\0'}},
1216         },
1217         /* slots_out */
1218         {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
1219          {"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
1220          {"face_map.out", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
1221          {"face_map_double.out", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},  /* duplicate faces */
1222          {{'\0'}},
1223         },
1224         bmo_triangulate_exec,
1225         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
1226          BMO_OPTYPE_FLAG_NORMALS_CALC |
1227          BMO_OPTYPE_FLAG_SELECT_FLUSH),
1228 };
1229
1230 /*
1231  * Un-Subdivide.
1232  *
1233  * Reduce detail in geometry containing grids.
1234  */
1235 static BMOpDefine bmo_unsubdivide_def = {
1236         "unsubdivide",
1237         /* slots_in */
1238         {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
1239          {"iterations", BMO_OP_SLOT_INT},
1240          {{'\0'}},
1241         },
1242         {{{'\0'}}},  /* no output */
1243         bmo_unsubdivide_exec,
1244         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
1245          BMO_OPTYPE_FLAG_NORMALS_CALC |
1246          BMO_OPTYPE_FLAG_SELECT_FLUSH |
1247          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
1248 };
1249
1250 static BMO_FlagSet bmo_enum_subdivide_edges_quad_corner_type[] = {
1251         {SUBD_CORNER_STRAIGHT_CUT, "STRAIGHT_CUT"},
1252         {SUBD_CORNER_INNERVERT, "INNER_VERT"},
1253         {SUBD_CORNER_PATH, "PATH"},
1254         {SUBD_CORNER_FAN, "FAN"},
1255         {0, NULL},
1256 };
1257
1258 /*
1259  * Subdivide Edges.
1260  *
1261  * Advanced operator for subdividing edges
1262  * with options for face patterns, smoothing and randomization.
1263  */
1264 static BMOpDefine bmo_subdivide_edges_def = {
1265         "subdivide_edges",
1266         /* slots_in */
1267         {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
1268          {"smooth", BMO_OP_SLOT_FLT},
1269          {"smooth_falloff", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, bmo_enum_falloff_type}, /* smooth falloff type */
1270          {"fractal", BMO_OP_SLOT_FLT},
1271          {"along_normal", BMO_OP_SLOT_FLT},
1272          {"cuts", BMO_OP_SLOT_INT},
1273          {"seed", BMO_OP_SLOT_INT},
1274          {"custom_patterns", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL}},  /* uses custom pointers */
1275          {"edge_percents", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_FLT}},
1276          {"quad_corner_type",  BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, bmo_enum_subdivide_edges_quad_corner_type}, /* quad corner type */
1277          {"use_grid_fill", BMO_OP_SLOT_BOOL},   /* fill in fully-selected faces with a grid */
1278          {"use_single_edge", BMO_OP_SLOT_BOOL}, /* tessellate the case of one edge selected in a quad or triangle */
1279          {"use_only_quads", BMO_OP_SLOT_BOOL},  /* only subdivide quads (for loopcut) */
1280          {"use_sphere", BMO_OP_SLOT_BOOL},     /* for making new primitives only */
1281          {"use_smooth_even", BMO_OP_SLOT_BOOL},  /* maintain even offset when smoothing */
1282          {{'\0'}},
1283         },
1284         /* slots_out */
1285         {/* these next three can have multiple types of elements in them */
1286          {"geom_inner.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1287          {"geom_split.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1288          {"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* contains all output geometry */
1289          {{'\0'}},
1290         },
1291         bmo_subdivide_edges_exec,
1292         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
1293          BMO_OPTYPE_FLAG_NORMALS_CALC |
1294          BMO_OPTYPE_FLAG_SELECT_FLUSH |
1295          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
1296 };
1297
1298 static BMO_FlagSet bmo_enum_subdivide_edgering_interp_mode[] = {
1299         {SUBD_RING_INTERP_LINEAR, "LINEAR"},
1300         {SUBD_RING_INTERP_PATH, "PATH"},
1301         {SUBD_RING_INTERP_SURF, "SURFACE"},
1302         {0, NULL},
1303 };
1304
1305 /*
1306  * Subdivide Edge-Ring.
1307  *
1308  * Take an edge-ring, and subdivide with interpolation options.
1309  */
1310 static BMOpDefine bmo_subdivide_edgering_def = {
1311         "subdivide_edgering",
1312         /* slots_in */
1313         {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input vertices */
1314          {"interp_mode", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, bmo_enum_subdivide_edgering_interp_mode}, /* interpolation method */
1315          {"smooth", BMO_OP_SLOT_FLT},
1316          {"cuts", BMO_OP_SLOT_INT},
1317          {"profile_shape", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, bmo_enum_falloff_type}, /* profile shape type */
1318          {"profile_shape_factor", BMO_OP_SLOT_FLT},
1319          {{'\0'}},
1320         },
1321         {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
1322          {{'\0'}}},
1323         bmo_subdivide_edgering_exec,
1324         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
1325          BMO_OPTYPE_FLAG_NORMALS_CALC |
1326          BMO_OPTYPE_FLAG_SELECT_FLUSH |
1327          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
1328 };
1329
1330 /*
1331  * Bisect Plane.
1332  *
1333  * Bisects the mesh by a plane (cut the mesh in half).
1334  */
1335 static BMOpDefine bmo_bisect_plane_def = {
1336         "bisect_plane",
1337         /* slots_in */
1338         {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1339          {"dist",         BMO_OP_SLOT_FLT},     /* minimum distance when testing if a vert is exactly on the plane */
1340          {"plane_co", BMO_OP_SLOT_VEC},         /* point on the plane */
1341          {"plane_no", BMO_OP_SLOT_VEC},         /* direction of the plane */
1342          {"use_snap_center", BMO_OP_SLOT_BOOL},  /* snap axis aligned verts to the center */
1343          {"clear_outer",   BMO_OP_SLOT_BOOL},    /* when enabled. remove all geometry on the positive side of the plane */
1344          {"clear_inner",   BMO_OP_SLOT_BOOL},    /* when enabled. remove all geometry on the negative side of the plane */
1345          {{'\0'}},
1346         },
1347         {{"geom_cut.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE}},  /* output geometry aligned with the plane (new and existing) */
1348          {"geom.out",     BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},  /* input and output geometry (result of cut)  */
1349          {{'\0'}}},
1350         bmo_bisect_plane_exec,
1351         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
1352          BMO_OPTYPE_FLAG_NORMALS_CALC |
1353          BMO_OPTYPE_FLAG_SELECT_FLUSH |
1354          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
1355 };
1356
1357 static BMO_FlagSet bmo_enum_delete_context[] = {
1358         {DEL_VERTS, "VERTS"},
1359         {DEL_EDGES, "EDGES"},
1360         {DEL_ONLYFACES, "FACES_ONLY"},
1361         {DEL_EDGESFACES, "EDGES_FACES"},
1362         {DEL_FACES, "FACES"},
1363         {DEL_FACES_KEEP_BOUNDARY, "FACES_KEEP_BOUNDARY"},
1364         {DEL_ONLYTAGGED, "TAGGED_ONLY"},
1365         {0, NULL},
1366 };
1367
1368 /*
1369  * Delete Geometry.
1370  *
1371  * Utility operator to delete geometry.
1372  */
1373 static BMOpDefine bmo_delete_def = {
1374         "delete",
1375         /* slots_in */
1376         {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1377          {"context", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, bmo_enum_delete_context}, /* geometry types to delete */
1378          {{'\0'}},
1379         },
1380         {{{'\0'}}},  /* no output */
1381         bmo_delete_exec,
1382         (BMO_OPTYPE_FLAG_NORMALS_CALC |
1383          BMO_OPTYPE_FLAG_SELECT_FLUSH |
1384          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
1385 };
1386
1387 /*
1388  * Duplicate Geometry.
1389  *
1390  * Utility operator to duplicate geometry,
1391  * optionally into a destination mesh.
1392  */
1393 static BMOpDefine bmo_duplicate_def = {
1394         "duplicate",
1395         /* slots_in */
1396         {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1397         /* destination bmesh, if NULL will use current on */
1398          {"dest", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_BMESH}},
1399          {"use_select_history", BMO_OP_SLOT_BOOL},
1400          {{'\0'}},
1401         },
1402         /* slots_out */
1403         {{"geom_orig.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1404          {"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1405         /* facemap maps from source faces to dupe
1406          * faces, and from dupe faces to source faces */
1407          {"vert_map.out", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
1408          {"edge_map.out", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
1409          {"face_map.out", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
1410          {"boundary_map.out", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
1411          {"isovert_map.out", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
1412          {{'\0'}},
1413         },
1414         bmo_duplicate_exec,
1415         (BMO_OPTYPE_FLAG_NORMALS_CALC |
1416          BMO_OPTYPE_FLAG_SELECT_FLUSH),
1417 };
1418
1419 /*
1420  * Split Off Geometry.
1421  *
1422  * Disconnect geometry from adjacent edges and faces,
1423  * optionally into a destination mesh.
1424  */
1425 static BMOpDefine bmo_split_def = {
1426         "split",
1427         /* slots_in */
1428         {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1429         /* destination bmesh, if NULL will use current one */
1430          {"dest", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_BMESH}},
1431          {"use_only_faces", BMO_OP_SLOT_BOOL},  /* when enabled. don't duplicate loose verts/edges */
1432          {{'\0'}},
1433         },
1434         /* slots_out */
1435         {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1436          {"boundary_map.out", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
1437          {"isovert_map.out", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
1438          {{'\0'}},
1439         },
1440         bmo_split_exec,
1441         (BMO_OPTYPE_FLAG_NORMALS_CALC |
1442          BMO_OPTYPE_FLAG_SELECT_FLUSH),
1443 };
1444
1445 /*
1446  * Spin.
1447  *
1448  * Extrude or duplicate geometry a number of times,
1449  * rotating and possibly translating after each step
1450  */
1451 static BMOpDefine bmo_spin_def = {
1452         "spin",
1453         /* slots_in */
1454         {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1455          {"cent", BMO_OP_SLOT_VEC},             /* rotation center */
1456          {"axis", BMO_OP_SLOT_VEC},             /* rotation axis */
1457          {"dvec", BMO_OP_SLOT_VEC},             /* translation delta per step */
1458          {"angle", BMO_OP_SLOT_FLT},            /* total rotation angle (radians) */
1459          {"space", BMO_OP_SLOT_MAT},            /* matrix to define the space (typically object matrix) */
1460          {"steps", BMO_OP_SLOT_INT},            /* number of steps */
1461          {"use_merge", BMO_OP_SLOT_BOOL},       /* Merge first/last when the angle is a full revolution. */
1462          {"use_normal_flip", BMO_OP_SLOT_BOOL}, /* Create faces with reversed direction. */
1463          {"use_duplicate", BMO_OP_SLOT_BOOL},   /* duplicate or extrude? */
1464          {{'\0'}},
1465         },
1466         /* slots_out */
1467         {{"geom_last.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* result of last step */
1468          {{'\0'}},
1469         },
1470         bmo_spin_exec,
1471         (BMO_OPTYPE_FLAG_NORMALS_CALC |
1472          BMO_OPTYPE_FLAG_SELECT_FLUSH),
1473 };
1474
1475 /*
1476  * UV Rotation.
1477  *
1478  * Cycle the loop UV's
1479  */
1480 static BMOpDefine bmo_rotate_uvs_def = {
1481         "rotate_uvs",
1482         /* slots_in */
1483         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},    /* input faces */
1484          {"use_ccw", BMO_OP_SLOT_BOOL},         /* rotate counter-clockwise if true, otherwise clockwise */
1485          {{'\0'}},
1486         },
1487         {{{'\0'}}},  /* no output */
1488         bmo_rotate_uvs_exec,
1489         (BMO_OPTYPE_FLAG_NOP),
1490 };
1491
1492 /*
1493  * UV Reverse.
1494  *
1495  * Reverse the UV's
1496  */
1497 static BMOpDefine bmo_reverse_uvs_def = {
1498         "reverse_uvs",
1499         /* slots_in */
1500         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},    /* input faces */
1501          {{'\0'}},
1502         },
1503         {{{'\0'}}},  /* no output */
1504         bmo_reverse_uvs_exec,
1505         (BMO_OPTYPE_FLAG_NOP),
1506 };
1507
1508 /*
1509  * Color Rotation.
1510  *
1511  * Cycle the loop colors
1512  */
1513 static BMOpDefine bmo_rotate_colors_def = {
1514         "rotate_colors",
1515         /* slots_in */
1516         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},    /* input faces */
1517          {"use_ccw", BMO_OP_SLOT_BOOL},         /* rotate counter-clockwise if true, otherwise clockwise */
1518          {{'\0'}},
1519         },
1520         {{{'\0'}}},  /* no output */
1521         bmo_rotate_colors_exec,
1522         (BMO_OPTYPE_FLAG_NOP),
1523 };
1524
1525 /*
1526  * Color Reverse
1527  *
1528  * Reverse the loop colors.
1529  */
1530 static BMOpDefine bmo_reverse_colors_def = {
1531         "reverse_colors",
1532         /* slots_in */
1533         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},    /* input faces */
1534          {{'\0'}},
1535         },
1536         {{{'\0'}}},  /* no output */
1537         bmo_reverse_colors_exec,
1538         (BMO_OPTYPE_FLAG_NOP),
1539 };
1540
1541 /*
1542  * Edge Split.
1543  *
1544  * Disconnects faces along input edges.
1545  */
1546 static BMOpDefine bmo_split_edges_def = {
1547         "split_edges",
1548         /* slots_in */
1549         {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},    /* input edges */
1550          /* needed for vertex rip so we can rip only half an edge at a boundary wich would otherwise split off */
1551          {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},    /* optional tag verts, use to have greater control of splits */
1552          {"use_verts",        BMO_OP_SLOT_BOOL}, /* use 'verts' for splitting, else just find verts to split from edges */
1553          {{'\0'}},
1554         },
1555         /* slots_out */
1556         {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* old output disconnected edges */
1557          {{'\0'}},
1558         },
1559         bmo_split_edges_exec,
1560         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
1561          BMO_OPTYPE_FLAG_NORMALS_CALC |
1562          BMO_OPTYPE_FLAG_SELECT_FLUSH),
1563 };
1564
1565 /*
1566  * Create Grid.
1567  *
1568  * Creates a grid with a variable number of subdivisions
1569  */
1570 static BMOpDefine bmo_create_grid_def = {
1571         "create_grid",
1572         /* slots_in */
1573         {{"x_segments",      BMO_OP_SLOT_INT},  /* number of x segments */
1574          {"y_segments",      BMO_OP_SLOT_INT},  /* number of y segments */
1575          {"size",            BMO_OP_SLOT_FLT},  /* size of the grid */
1576          {"matrix",          BMO_OP_SLOT_MAT},  /* matrix to multiply the new geometry with */
1577          {"calc_uvs",        BMO_OP_SLOT_BOOL}, /* calculate default UVs */
1578          {{'\0'}},
1579         },
1580         /* slots_out */
1581         {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
1582          {{'\0'}},
1583         },
1584         bmo_create_grid_exec,
1585         (BMO_OPTYPE_FLAG_NORMALS_CALC |
1586          BMO_OPTYPE_FLAG_SELECT_FLUSH),
1587 };
1588
1589 /*
1590  * Create UV Sphere.
1591  *
1592  * Creates a grid with a variable number of subdivisions
1593  */
1594 static BMOpDefine bmo_create_uvsphere_def = {
1595         "create_uvsphere",
1596         /* slots_in */
1597         {{"u_segments",      BMO_OP_SLOT_INT}, /* number of u segments */
1598          {"v_segments",      BMO_OP_SLOT_INT}, /* number of v segment */
1599          {"diameter",        BMO_OP_SLOT_FLT}, /* diameter */
1600          {"matrix",          BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */
1601          {"calc_uvs",        BMO_OP_SLOT_BOOL}, /* calculate default UVs */
1602          {{'\0'}},
1603         },
1604         /* slots_out */
1605         {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
1606          {{'\0'}},
1607         },
1608         bmo_create_uvsphere_exec,
1609         (BMO_OPTYPE_FLAG_NORMALS_CALC |
1610          BMO_OPTYPE_FLAG_SELECT_FLUSH),
1611 };
1612
1613 /*
1614  * Create Ico-Sphere.
1615  *
1616  * Creates a grid with a variable number of subdivisions
1617  */
1618 static BMOpDefine bmo_create_icosphere_def = {
1619         "create_icosphere",
1620         /* slots_in */
1621         {{"subdivisions",    BMO_OP_SLOT_INT}, /* how many times to recursively subdivide the sphere */
1622          {"diameter",        BMO_OP_SLOT_FLT}, /* diameter */
1623          {"matrix",          BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */
1624          {"calc_uvs",        BMO_OP_SLOT_BOOL}, /* calculate default UVs */
1625          {{'\0'}},
1626         },
1627         /* slots_out */
1628         {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
1629          {{'\0'}},
1630         },
1631         bmo_create_icosphere_exec,
1632         (BMO_OPTYPE_FLAG_NORMALS_CALC |
1633          BMO_OPTYPE_FLAG_SELECT_FLUSH),
1634 };
1635
1636 /*
1637  * Create Suzanne.
1638  *
1639  * Creates a monkey (standard blender primitive).
1640  */
1641 static BMOpDefine bmo_create_monkey_def = {
1642         "create_monkey",
1643         /* slots_in */
1644         {{"matrix",    BMO_OP_SLOT_MAT},  /* matrix to multiply the new geometry with */
1645          {"calc_uvs",  BMO_OP_SLOT_BOOL}, /* calculate default UVs */
1646          {{'\0'}},
1647         },
1648         /* slots_out */
1649         {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
1650          {{'\0'}},
1651         },
1652         bmo_create_monkey_exec,
1653         (BMO_OPTYPE_FLAG_NORMALS_CALC |
1654          BMO_OPTYPE_FLAG_SELECT_FLUSH),
1655 };
1656
1657 /*
1658  * Create Cone.
1659  *
1660  * Creates a cone with variable depth at both ends
1661  */
1662 static BMOpDefine bmo_create_cone_def = {
1663         "create_cone",
1664         /* slots_in */
1665         {{"cap_ends",        BMO_OP_SLOT_BOOL},  /* whether or not to fill in the ends with faces */
1666          {"cap_tris",        BMO_OP_SLOT_BOOL},  /* fill ends with triangles instead of ngons */
1667          {"segments",        BMO_OP_SLOT_INT},
1668          {"diameter1",       BMO_OP_SLOT_FLT},  /* diameter of one end */
1669          {"diameter2",       BMO_OP_SLOT_FLT},  /* diameter of the opposite */
1670          {"depth",           BMO_OP_SLOT_FLT},  /* distance between ends */
1671          {"matrix",          BMO_OP_SLOT_MAT},  /* matrix to multiply the new geometry with */
1672          {"calc_uvs",        BMO_OP_SLOT_BOOL}, /* calculate default UVs */
1673          {{'\0'}},
1674         },
1675         /* slots_out */
1676         {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
1677          {{'\0'}},
1678         },
1679         bmo_create_cone_exec,
1680         (BMO_OPTYPE_FLAG_NORMALS_CALC |
1681          BMO_OPTYPE_FLAG_SELECT_FLUSH),
1682 };
1683
1684 /*
1685  * Creates a Circle.
1686  */
1687 static BMOpDefine bmo_create_circle_def = {
1688         "create_circle",
1689         /* slots_in */
1690         {{"cap_ends",        BMO_OP_SLOT_BOOL},  /* whether or not to fill in the ends with faces */
1691          {"cap_tris",        BMO_OP_SLOT_BOOL},  /* fill ends with triangles instead of ngons */
1692          {"segments",        BMO_OP_SLOT_INT},
1693          {"radius",          BMO_OP_SLOT_FLT},  /* Radius of the circle. */
1694          {"matrix",          BMO_OP_SLOT_MAT},  /* matrix to multiply the new geometry with */
1695          {"calc_uvs",        BMO_OP_SLOT_BOOL}, /* calculate default UVs */
1696          {{'\0'}},
1697         },
1698         /* slots_out */
1699         {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
1700          {{'\0'}},
1701         },
1702         bmo_create_circle_exec,
1703         (BMO_OPTYPE_FLAG_NORMALS_CALC |
1704          BMO_OPTYPE_FLAG_SELECT_FLUSH),
1705 };
1706
1707 /*
1708  * Create Cube
1709  *
1710  * Creates a cube.
1711  */
1712 static BMOpDefine bmo_create_cube_def = {
1713         "create_cube",
1714         /* slots_in */
1715         {{"size",            BMO_OP_SLOT_FLT},  /* size of the cube */
1716          {"matrix",          BMO_OP_SLOT_MAT},  /* matrix to multiply the new geometry with */
1717          {"calc_uvs",        BMO_OP_SLOT_BOOL}, /* calculate default UVs */
1718          {{'\0'}},
1719         },
1720         /* slots_out */
1721         {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
1722          {{'\0'}},
1723         },
1724         bmo_create_cube_exec,
1725         (BMO_OPTYPE_FLAG_NORMALS_CALC |
1726          BMO_OPTYPE_FLAG_SELECT_FLUSH),
1727 };
1728
1729 static BMO_FlagSet bmo_enum_bevel_offset_type[] = {
1730         {BEVEL_AMT_OFFSET, "OFFSET"},
1731         {BEVEL_AMT_WIDTH, "WIDTH"},
1732         {BEVEL_AMT_DEPTH, "DEPTH"},
1733         {BEVEL_AMT_PERCENT, "PERCENT"},
1734         {0, NULL},
1735 };
1736
1737 static BMO_FlagSet bmo_enum_bevel_face_strength_type[] = {
1738         {BEVEL_FACE_STRENGTH_NONE, "NONE"},
1739         {BEVEL_FACE_STRENGTH_NEW, "NEW"},
1740         {BEVEL_FACE_STRENGTH_AFFECTED, "AFFECTED"},
1741         {BEVEL_FACE_STRENGTH_ALL, "ALL"},
1742         {0, NULL},
1743 };
1744
1745 /*
1746  * Bevel.
1747  *
1748  * Bevels edges and vertices
1749  */
1750 static BMOpDefine bmo_bevel_def = {
1751         "bevel",
1752         /* slots_in */
1753         {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},     /* input edges and vertices */
1754          {"offset", BMO_OP_SLOT_FLT},           /* amount to offset beveled edge */
1755          {"offset_type", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, bmo_enum_bevel_offset_type}, /* how to measure the offset */
1756          {"segments", BMO_OP_SLOT_INT},         /* number of segments in bevel */
1757          {"profile", BMO_OP_SLOT_FLT},          /* profile shape, 0->1 (.5=>round) */
1758          {"vertex_only", BMO_OP_SLOT_BOOL},     /* only bevel vertices, not edges */
1759          {"clamp_overlap", BMO_OP_SLOT_BOOL},   /* do not allow beveled edges/vertices to overlap each other */
1760          {"material", BMO_OP_SLOT_INT},         /* material for bevel faces, -1 means get from adjacent faces */
1761          {"loop_slide", BMO_OP_SLOT_BOOL},      /* prefer to slide along edges to having even widths */
1762          {"mark_seam", BMO_OP_SLOT_BOOL},               /* extend edge data to allow seams to run across bevels */
1763          {"mark_sharp", BMO_OP_SLOT_BOOL},              /* extend edge data to allow sharp edges to run across bevels */
1764          {"harden_normals", BMO_OP_SLOT_BOOL},  /* harden normals */
1765          {"face_strength_mode", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM},
1766                 bmo_enum_bevel_face_strength_type}, /* whether to set face strength, and which faces to set if so */
1767          {{'\0'}},
1768         },
1769         /* slots_out */
1770         {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
1771          {"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* output edges */
1772          {"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
1773          {{'\0'}},
1774         },
1775
1776         bmo_bevel_exec,
1777         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
1778          BMO_OPTYPE_FLAG_NORMALS_CALC |
1779          BMO_OPTYPE_FLAG_SELECT_FLUSH |
1780          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
1781 };
1782
1783 /* no enum is defined for this */
1784 static BMO_FlagSet bmo_enum_beautify_fill_method[] = {
1785         {0, "AREA"},
1786         {1, "ANGLE"},
1787         {0, NULL},
1788 };
1789
1790 /*
1791  * Beautify Fill.
1792  *
1793  * Rotate edges to create more evenly spaced triangles.
1794  */
1795 static BMOpDefine bmo_beautify_fill_def = {
1796         "beautify_fill",
1797         /* slots_in */
1798         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
1799          {"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* edges that can be flipped */
1800          {"use_restrict_tag", BMO_OP_SLOT_BOOL}, /* restrict edge rotation to mixed tagged vertices */
1801          {"method", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, bmo_enum_beautify_fill_method}, /* method to define what is beautiful */
1802          {{'\0'}},
1803         },
1804         /* slots_out */
1805         {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* new flipped faces and edges */
1806          {{'\0'}},
1807         },
1808         bmo_beautify_fill_exec,
1809         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
1810          BMO_OPTYPE_FLAG_NORMALS_CALC |
1811          BMO_OPTYPE_FLAG_SELECT_FLUSH |
1812          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
1813 };
1814
1815 /*
1816  * Triangle Fill.
1817  *
1818  * Fill edges with triangles
1819  */
1820 static BMOpDefine bmo_triangle_fill_def = {
1821         "triangle_fill",
1822         /* slots_in */
1823         {{"use_beauty", BMO_OP_SLOT_BOOL},
1824          {"use_dissolve", BMO_OP_SLOT_BOOL},  /* dissolve resulting faces */
1825          {"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},    /* input edges */
1826          {"normal", BMO_OP_SLOT_VEC},  /* optionally pass the fill normal to use */
1827          {{'\0'}},
1828         },
1829         /* slots_out */
1830         {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* new faces and edges */
1831          {{'\0'}},
1832         },
1833         bmo_triangle_fill_exec,
1834         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
1835          BMO_OPTYPE_FLAG_NORMALS_CALC |
1836          BMO_OPTYPE_FLAG_SELECT_FLUSH),
1837 };
1838
1839 /*
1840  * Solidify.
1841  *
1842  * Turns a mesh into a shell with thickness
1843  */
1844 static BMOpDefine bmo_solidify_def = {
1845         "solidify",
1846         /* slots_in */
1847         {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1848          {"thickness", BMO_OP_SLOT_FLT},
1849          {{'\0'}},
1850         },
1851         /* slots_out */
1852         {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1853          {{'\0'}},
1854         },
1855         bmo_solidify_face_region_exec,
1856         (BMO_OPTYPE_FLAG_NORMALS_CALC |
1857          BMO_OPTYPE_FLAG_SELECT_FLUSH),
1858 };
1859
1860 /*
1861  * Face Inset (Individual).
1862  *
1863  * Insets individual faces.
1864  */
1865 static BMOpDefine bmo_inset_individual_def = {
1866         "inset_individual",
1867         /* slots_in */
1868         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},    /* input faces */
1869          {"thickness", BMO_OP_SLOT_FLT},
1870          {"depth", BMO_OP_SLOT_FLT},
1871          {"use_even_offset", BMO_OP_SLOT_BOOL},
1872          {"use_interpolate", BMO_OP_SLOT_BOOL},
1873          {"use_relative_offset", BMO_OP_SLOT_BOOL},
1874          {{'\0'}},
1875         },
1876         /* slots_out */
1877         {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
1878          {{'\0'}},
1879         },
1880         bmo_inset_individual_exec,
1881         /* caller needs to handle BMO_OPTYPE_FLAG_SELECT_FLUSH */
1882         (BMO_OPTYPE_FLAG_NORMALS_CALC),
1883 };
1884
1885 /*
1886  * Face Inset (Regions).
1887  *
1888  * Inset or outset face regions.
1889  */
1890 static BMOpDefine bmo_inset_region_def = {
1891         "inset_region",
1892         /* slots_in */
1893         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},    /* input faces */
1894          {"faces_exclude", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
1895          {"use_boundary", BMO_OP_SLOT_BOOL},
1896          {"use_even_offset", BMO_OP_SLOT_BOOL},
1897          {"use_interpolate", BMO_OP_SLOT_BOOL},
1898          {"use_relative_offset", BMO_OP_SLOT_BOOL},
1899          {"use_edge_rail", BMO_OP_SLOT_BOOL},
1900          {"thickness", BMO_OP_SLOT_FLT},
1901          {"depth", BMO_OP_SLOT_FLT},
1902          {"use_outset", BMO_OP_SLOT_BOOL},
1903          {{'\0'}},
1904         },
1905         /* slots_out */
1906         {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
1907          {{'\0'}},
1908         },
1909         bmo_inset_region_exec,
1910         (BMO_OPTYPE_FLAG_NORMALS_CALC |
1911          BMO_OPTYPE_FLAG_SELECT_FLUSH),
1912 };
1913
1914 /*
1915  * Edgeloop Offset.
1916  *
1917  * Creates edge loops based on simple edge-outset method.
1918  */
1919 static BMOpDefine bmo_offset_edgeloops_def = {
1920         "offset_edgeloops",
1921         /* slots_in */
1922         {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},    /* input faces */
1923          {"use_cap_endpoint", BMO_OP_SLOT_BOOL},
1924          {{'\0'}},
1925         },
1926         /* slots_out */
1927         {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* output faces */
1928          {{'\0'}},
1929         },
1930         bmo_offset_edgeloops_exec,
1931         (BMO_OPTYPE_FLAG_NORMALS_CALC |
1932          BMO_OPTYPE_FLAG_SELECT_FLUSH),
1933 };
1934
1935 /*
1936  * Wire Frame.
1937  *
1938  * Makes a wire-frame copy of faces.
1939  */
1940 static BMOpDefine bmo_wireframe_def = {
1941         "wireframe",
1942         /* slots_in */
1943         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},   /* input faces */
1944          {"thickness", BMO_OP_SLOT_FLT},
1945          {"offset", BMO_OP_SLOT_FLT},
1946          {"use_replace", BMO_OP_SLOT_BOOL},
1947          {"use_boundary", BMO_OP_SLOT_BOOL},
1948          {"use_even_offset", BMO_OP_SLOT_BOOL},
1949          {"use_crease", BMO_OP_SLOT_BOOL},
1950          {"crease_weight", BMO_OP_SLOT_FLT},
1951          {"use_relative_offset", BMO_OP_SLOT_BOOL},
1952          {"material_offset", BMO_OP_SLOT_INT},
1953          {{'\0'}},
1954         },
1955         /* slots_out */
1956         {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
1957          {{'\0'}},
1958         },
1959         bmo_wireframe_exec,
1960         (BMO_OPTYPE_FLAG_NORMALS_CALC |
1961          BMO_OPTYPE_FLAG_SELECT_FLUSH |
1962          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
1963 };
1964
1965 static BMO_FlagSet bmo_enum_poke_center_mode[] = {
1966         {BMOP_POKE_MEDIAN_WEIGHTED, "MEAN_WEIGHTED"},
1967         {BMOP_POKE_MEDIAN, "MEAN"},
1968         {BMOP_POKE_BOUNDS, "BOUNDS"},
1969         {0, NULL},
1970 };
1971
1972 /*
1973  * Pokes a face.
1974  *
1975  * Splits a face into a triangle fan.
1976  */
1977 static BMOpDefine bmo_poke_def = {
1978         "poke",
1979         /* slots_in */
1980         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},   /* input faces */
1981          {"offset", BMO_OP_SLOT_FLT}, /* center vertex offset along normal */
1982          {"center_mode", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, bmo_enum_poke_center_mode}, /* calculation mode for center vertex */
1983          {"use_relative_offset", BMO_OP_SLOT_BOOL}, /* apply offset */
1984          {{'\0'}},
1985         },
1986         /* slots_out */
1987         {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
1988          {"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
1989          {{'\0'}},
1990         },
1991         bmo_poke_exec,
1992         (BMO_OPTYPE_FLAG_NORMALS_CALC |
1993          BMO_OPTYPE_FLAG_SELECT_FLUSH |
1994          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
1995 };
1996
1997 #ifdef WITH_BULLET
1998 /*
1999  * Convex Hull
2000  *
2001  * Builds a convex hull from the vertices in 'input'.
2002  *
2003  * If 'use_existing_faces' is true, the hull will not output triangles
2004  * that are covered by a pre-existing face.
2005  *
2006  * All hull vertices, faces, and edges are added to 'geom.out'. Any
2007  * input elements that end up inside the hull (i.e. are not used by an
2008  * output face) are added to the 'interior_geom' slot. The
2009  * 'unused_geom' slot will contain all interior geometry that is
2010  * completely unused. Lastly, 'holes_geom' contains edges and faces
2011  * that were in the input and are part of the hull.
2012  */
2013 static BMOpDefine bmo_convex_hull_def = {
2014         "convex_hull",
2015         /* slots_in */
2016         {{"input", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
2017          {"use_existing_faces", BMO_OP_SLOT_BOOL},
2018          {{'\0'}},
2019         },
2020         /* slots_out */
2021         {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
2022          {"geom_interior.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
2023          {"geom_unused.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
2024          {"geom_holes.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
2025          {{'\0'}},
2026         },
2027         bmo_convex_hull_exec,
2028         (BMO_OPTYPE_FLAG_NORMALS_CALC |
2029          BMO_OPTYPE_FLAG_SELECT_FLUSH |
2030          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
2031 };
2032 #endif
2033
2034 /*
2035  * Symmetrize.
2036  *
2037  * Makes the mesh elements in the "input" slot symmetrical. Unlike
2038  * normal mirroring, it only copies in one direction, as specified by
2039  * the "direction" slot. The edges and faces that cross the plane of
2040  * symmetry are split as needed to enforce symmetry.
2041  *
2042  * All new vertices, edges, and faces are added to the "geom.out" slot.
2043  */
2044 static BMOpDefine bmo_symmetrize_def = {
2045         "symmetrize",
2046         /* slots_in */
2047         {{"input", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
2048          {"direction", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, bmo_enum_axis_xyz}, /* axis to use */
2049          {"dist", BMO_OP_SLOT_FLT}, /* minimum distance */
2050          {{'\0'}},
2051         },
2052         /* slots_out */
2053         {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
2054          {{'\0'}},
2055         },
2056         bmo_symmetrize_exec,
2057         (BMO_OPTYPE_FLAG_NORMALS_CALC |
2058          BMO_OPTYPE_FLAG_SELECT_FLUSH |
2059          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
2060 };
2061
2062 const BMOpDefine *bmo_opdefines[] = {
2063         &bmo_automerge_def,
2064         &bmo_average_vert_facedata_def,
2065         &bmo_beautify_fill_def,
2066         &bmo_bevel_def,
2067         &bmo_bisect_edges_def,
2068         &bmo_bmesh_to_mesh_def,
2069         &bmo_bridge_loops_def,
2070         &bmo_collapse_def,
2071         &bmo_collapse_uvs_def,
2072         &bmo_connect_verts_def,
2073         &bmo_connect_verts_concave_def,
2074         &bmo_connect_verts_nonplanar_def,
2075         &bmo_connect_vert_pair_def,
2076         &bmo_contextual_create_def,
2077 #ifdef WITH_BULLET
2078         &bmo_convex_hull_def,
2079 #endif
2080         &bmo_create_circle_def,
2081         &bmo_create_cone_def,
2082         &bmo_create_cube_def,
2083         &bmo_create_grid_def,
2084         &bmo_create_icosphere_def,
2085         &bmo_create_monkey_def,
2086         &bmo_create_uvsphere_def,
2087         &bmo_create_vert_def,
2088         &bmo_delete_def,
2089         &bmo_dissolve_edges_def,
2090         &bmo_dissolve_faces_def,
2091         &bmo_dissolve_verts_def,
2092         &bmo_dissolve_limit_def,
2093         &bmo_dissolve_degenerate_def,
2094         &bmo_duplicate_def,
2095         &bmo_holes_fill_def,
2096         &bmo_face_attribute_fill_def,
2097         &bmo_offset_edgeloops_def,
2098         &bmo_edgeloop_fill_def,
2099         &bmo_edgenet_fill_def,
2100         &bmo_edgenet_prepare_def,
2101         &bmo_extrude_discrete_faces_def,
2102         &bmo_extrude_edge_only_def,
2103         &bmo_extrude_face_region_def,
2104         &bmo_extrude_vert_indiv_def,
2105         &bmo_find_doubles_def,
2106         &bmo_grid_fill_def,
2107         &bmo_inset_individual_def,
2108         &bmo_inset_region_def,
2109         &bmo_join_triangles_def,
2110         &bmo_mesh_to_bmesh_def,
2111         &bmo_mirror_def,
2112         &bmo_object_load_bmesh_def,
2113         &bmo_pointmerge_def,
2114         &bmo_pointmerge_facedata_def,
2115         &bmo_poke_def,
2116         &bmo_recalc_face_normals_def,
2117         &bmo_planar_faces_def,
2118         &bmo_region_extend_def,
2119         &bmo_remove_doubles_def,
2120         &bmo_reverse_colors_def,
2121         &bmo_reverse_faces_def,
2122         &bmo_reverse_uvs_def,
2123         &bmo_rotate_colors_def,
2124         &bmo_rotate_def,
2125         &bmo_rotate_edges_def,
2126         &bmo_rotate_uvs_def,
2127         &bmo_scale_def,
2128         &bmo_smooth_vert_def,
2129         &bmo_smooth_laplacian_vert_def,
2130         &bmo_solidify_def,
2131         &bmo_spin_def,
2132         &bmo_split_def,
2133         &bmo_split_edges_def,
2134         &bmo_subdivide_edges_def,
2135         &bmo_subdivide_edgering_def,
2136         &bmo_bisect_plane_def,
2137         &bmo_symmetrize_def,
2138         &bmo_transform_def,
2139         &bmo_translate_def,
2140         &bmo_triangle_fill_def,
2141         &bmo_triangulate_def,
2142         &bmo_unsubdivide_def,
2143         &bmo_weld_verts_def,
2144         &bmo_wireframe_def,
2145 };
2146
2147 const int bmo_opdefines_total = ARRAY_SIZE(bmo_opdefines);