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