Merging r58464 through r58474 from trunk into soc-2013-depsgraph_mt
[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          {{'\0'}},
522         },
523         /* slots_out */
524         {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* new faces */
525          {"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* new edges */
526          {{'\0'}},
527         },
528         bmo_bridge_loops_exec,
529         BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
530 };
531
532 /*
533  * Grid Fill.
534  *
535  * Create faces defined by 2 disconnected edge loops (which share edges).
536  */
537 static BMOpDefine bmo_grid_fill_def = {
538         "grid_fill",
539         /* slots_in */
540         {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
541         /* restricts edges to groups.  maps edges to integer */
542          {"mat_nr",         BMO_OP_SLOT_INT},      /* material to use */
543          {"use_smooth",     BMO_OP_SLOT_BOOL},     /* smooth state to use */
544          {{'\0'}},
545         },
546         /* slots_out */
547         /* maps new faces to the group numbers they came from */
548         {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},     /* new faces */
549          {{'\0'}},
550         },
551         bmo_grid_fill_exec,
552         BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
553 };
554
555 /*
556  * Edge Loop Fill.
557  *
558  * Create faces defined by one or more non overlapping edge loops.
559  */
560 static BMOpDefine bmo_edgeloop_fill_def = {
561         "edgeloop_fill",
562         /* slots_in */
563         {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
564         /* restricts edges to groups.  maps edges to integer */
565          {"mat_nr",         BMO_OP_SLOT_INT},      /* material to use */
566          {"use_smooth",        BMO_OP_SLOT_BOOL},  /* smooth state to use */
567          {{'\0'}},
568         },
569         /* slots_out */
570         /* maps new faces to the group numbers they came from */
571         {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},     /* new faces */
572          {{'\0'}},
573         },
574         bmo_edgeloop_fill_exec,
575         BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
576 };
577
578
579 /*
580  * Edge Net Fill.
581  *
582  * Create faces defined by enclosed edges.
583  */
584 static BMOpDefine bmo_edgenet_fill_def = {
585         "edgenet_fill",
586         /* slots_in */
587         {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
588         /* restricts edges to groups.  maps edges to integer */
589          {"restrict",     BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_BOOL}},
590          {"use_restrict",        BMO_OP_SLOT_BOOL},
591          {"use_fill_check",        BMO_OP_SLOT_BOOL},
592          {"exclude_faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* list of faces to ignore for manifold check */
593          {"mat_nr",         BMO_OP_SLOT_INT},      /* material to use */
594          {"use_smooth",        BMO_OP_SLOT_BOOL},  /* smooth state to use */
595          {{'\0'}},
596         },
597         /* slots_out */
598         /* maps new faces to the group numbers they came from */
599         {{"face_groupmap.out",     BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
600          {"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},     /* new faces */
601          {{'\0'}},
602         },
603         bmo_edgenet_fill_exec,
604         BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
605 };
606
607 /*
608  * Edgenet Prepare.
609  *
610  * Identifies several useful edge loop cases and modifies them so
611  * they'll become a face when edgenet_fill is called.  The cases covered are:
612  *
613  * - One single loop; an edge is added to connect the ends
614  * - Two loops; two edges are added to connect the endpoints (based on the
615  *   shortest distance between each endpont).
616  */
617 static BMOpDefine bmo_edgenet_prepare_def = {
618         "edgenet_prepare",
619         /* slots_in */
620         {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},    /* input edges */
621          {{'\0'}},
622         },
623         /* slots_out */
624         {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},  /* new edges */
625          {{'\0'}},
626         },
627         bmo_edgenet_prepare_exec,
628         BMO_OPTYPE_FLAG_NOP,
629 };
630
631 /*
632  * Rotate.
633  *
634  * Rotate vertices around a center, using a 3x3 rotation matrix.
635  */
636 static BMOpDefine bmo_rotate_def = {
637         "rotate",
638         /* slots_in */
639         {{"cent",            BMO_OP_SLOT_VEC},  /* center of rotation */
640          {"matrix",          BMO_OP_SLOT_MAT},  /* matrix defining rotation */
641          {"verts",           BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},  /* input vertices */
642          {{'\0'}},
643         },
644         {{{'\0'}}},  /* no output */
645         bmo_rotate_exec,
646         BMO_OPTYPE_FLAG_NORMALS_CALC,
647 };
648
649 /*
650  * Translate.
651  *
652  * Translate vertices by an offset.
653  */
654 static BMOpDefine bmo_translate_def = {
655         "translate",
656         /* slots_in */
657         {{"vec", BMO_OP_SLOT_VEC},  /* translation offset */
658          {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},  /* input vertices */
659          {{'\0'}},
660         },
661         {{{'\0'}}},  /* no output */
662         bmo_translate_exec,
663         BMO_OPTYPE_FLAG_NORMALS_CALC,
664 };
665
666 /*
667  * Scale.
668  *
669  * Scales vertices by an offset.
670  */
671 static BMOpDefine bmo_scale_def = {
672         "scale",
673         /* slots_in */
674         {{"vec", BMO_OP_SLOT_VEC},  /* scale factor */
675          {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},  /* input vertices */
676          {{'\0'}},
677         },
678         {{{'\0'}}},  /* no output */
679         bmo_scale_exec,
680         BMO_OPTYPE_FLAG_NORMALS_CALC,
681 };
682
683
684 /*
685  * Transform.
686  *
687  * Transforms a set of vertices by a matrix.  Multiplies
688  * the vertex coordinates with the matrix.
689  */
690 static BMOpDefine bmo_transform_def = {
691         "transform",
692         /* slots_in */
693         {{"matrix",          BMO_OP_SLOT_MAT},  /* transform matrix */
694          {"verts",           BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},  /* input vertices */
695          {{'\0'}},
696         },
697         {{{'\0'}}},  /* no output */
698         bmo_transform_exec,
699         BMO_OPTYPE_FLAG_NORMALS_CALC,
700 };
701
702 /*
703  * Object Load BMesh.
704  *
705  * Loads a bmesh into an object/mesh.  This is a "private"
706  * bmop.
707  */
708 static BMOpDefine bmo_object_load_bmesh_def = {
709         "object_load_bmesh",
710         /* slots_in */
711         {{"scene", BMO_OP_SLOT_PTR, {BMO_OP_SLOT_SUBTYPE_PTR_SCENE}},
712          {"object", BMO_OP_SLOT_PTR, {BMO_OP_SLOT_SUBTYPE_PTR_OBJECT}},
713          {{'\0'}},
714         },
715         {{{'\0'}}},  /* no output */
716         bmo_object_load_bmesh_exec,
717         BMO_OPTYPE_FLAG_NOP,
718 };
719
720
721 /*
722  * BMesh to Mesh.
723  *
724  * Converts a bmesh to a Mesh.  This is reserved for exiting editmode.
725  */
726 static BMOpDefine bmo_bmesh_to_mesh_def = {
727         "bmesh_to_mesh",
728         /* slots_in */
729         {
730         /* pointer to a mesh structure to fill in */
731          {"mesh", BMO_OP_SLOT_PTR, {BMO_OP_SLOT_SUBTYPE_PTR_MESH}},
732         /* pointer to an object structure */
733          {"object", BMO_OP_SLOT_PTR, {BMO_OP_SLOT_SUBTYPE_PTR_OBJECT}},
734          {"skip_tessface", BMO_OP_SLOT_BOOL},  /* don't calculate mfaces */
735          {{'\0'}},
736         },
737         {{{'\0'}}},  /* no output */
738         bmo_bmesh_to_mesh_exec,
739         BMO_OPTYPE_FLAG_NOP,
740 };
741
742 /*
743  * Mesh to BMesh.
744  *
745  * Load the contents of a mesh into the bmesh.  this bmop is private, it's
746  * reserved exclusively for entering editmode.
747  */
748 static BMOpDefine bmo_mesh_to_bmesh_def = {
749         "mesh_to_bmesh",
750         /* slots_in */
751         {
752         /* pointer to a Mesh structure */
753          {"mesh", BMO_OP_SLOT_PTR, {BMO_OP_SLOT_SUBTYPE_PTR_MESH}},
754         /* pointer to an Object structure */
755          {"object", BMO_OP_SLOT_PTR, {BMO_OP_SLOT_SUBTYPE_PTR_OBJECT}},
756          {"use_shapekey", BMO_OP_SLOT_BOOL},  /* load active shapekey coordinates into verts */
757          {{'\0'}},
758         },
759         {{{'\0'}}},  /* no output */
760         bmo_mesh_to_bmesh_exec,
761         BMO_OPTYPE_FLAG_NOP,
762 };
763
764 /*
765  * Individual Face Extrude.
766  *
767  * Extrudes faces individually.
768  */
769 static BMOpDefine bmo_extrude_discrete_faces_def = {
770         "extrude_discrete_faces",
771         /* slots_in */
772         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},     /* input faces */
773          {{'\0'}},
774         },
775         /* slots_out */
776         {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},   /* output faces */
777          {{'\0'}},
778         },
779         bmo_extrude_discrete_faces_exec,
780         BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
781 };
782
783 /*
784  * Extrude Only Edges.
785  *
786  * Extrudes Edges into faces, note that this is very simple, there's no fancy
787  * winged extrusion.
788  */
789 static BMOpDefine bmo_extrude_edge_only_def = {
790         "extrude_edge_only",
791         /* slots_in */
792         {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},    /* input vertices */
793          {{'\0'}},
794         },
795         /* slots_out */
796         {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},  /* output geometry */
797          {{'\0'}},
798         },
799         bmo_extrude_edge_only_exec,
800         BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
801 };
802
803 /*
804  * Individual Vertex Extrude.
805  *
806  * Extrudes wire edges from vertices.
807  */
808 static BMOpDefine bmo_extrude_vert_indiv_def = {
809         "extrude_vert_indiv",
810         /* slots_in */
811         {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},    /* input vertices */
812          {{'\0'}},
813         },
814         /* slots_out */
815         {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},  /* output wire edges */
816          {"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},  /* output vertices */
817          {{'\0'}},
818         },
819         bmo_extrude_vert_indiv_exec,
820         BMO_OPTYPE_FLAG_SELECT_FLUSH,
821 };
822
823 /*
824  * Connect Verts.
825  *
826  * Split faces by adding edges that connect **verts**.
827  */
828 static BMOpDefine bmo_connect_verts_def = {
829         "connect_verts",
830         /* slots_in */
831         {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},
832          {{'\0'}},
833         },
834         /* slots_out */
835         {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
836          {{'\0'}},
837         },
838         bmo_connect_verts_exec,
839         BMO_OPTYPE_FLAG_UNTAN_MULTIRES | BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
840 };
841
842 /*
843  * Connect Verts.
844  *
845  * Split faces by adding edges that connect **verts**.
846  */
847 static BMOpDefine bmo_connect_vert_pair_def = {
848         "connect_vert_pair",
849         /* slots_in */
850         {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},
851          {{'\0'}},
852         },
853         /* slots_out */
854         {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
855          {{'\0'}},
856         },
857         bmo_connect_vert_pair_exec,
858         BMO_OPTYPE_FLAG_UNTAN_MULTIRES | BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
859 };
860
861
862 /*
863  * Extrude Faces.
864  *
865  * Extrude operator (does not transform)
866  */
867 static BMOpDefine bmo_extrude_face_region_def = {
868         "extrude_face_region",
869         /* slots_in */
870         {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},     /* edges and faces */
871          {"edges_exclude", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_EMPTY}},
872          {"use_keep_orig", BMO_OP_SLOT_BOOL},   /* keep original geometry */
873          {{'\0'}},
874         },
875         /* slots_out */
876         {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
877          {{'\0'}},
878         },
879         bmo_extrude_face_region_exec,
880         BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
881 };
882
883 /*
884  * Dissolve Verts.
885  */
886 static BMOpDefine bmo_dissolve_verts_def = {
887         "dissolve_verts",
888         /* slots_in */
889         {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},
890          {"use_face_split", BMO_OP_SLOT_BOOL},
891          {{'\0'}},
892         },
893         {{{'\0'}}},  /* no output */
894         bmo_dissolve_verts_exec,
895         BMO_OPTYPE_FLAG_UNTAN_MULTIRES | BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
896 };
897
898 /*
899  * Dissolve Edges.
900  */
901 static BMOpDefine bmo_dissolve_edges_def = {
902         "dissolve_edges",
903         /* slots_in */
904         {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
905          {"use_verts", BMO_OP_SLOT_BOOL},  /* dissolve verts left between only 2 edges. */
906          {"use_face_split", BMO_OP_SLOT_BOOL},
907          {{'\0'}},
908         },
909         /* slots_out */
910         {{"region.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
911          {{'\0'}},
912         },
913         bmo_dissolve_edges_exec,
914         BMO_OPTYPE_FLAG_UNTAN_MULTIRES | BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
915 };
916
917 /*
918  * Dissolve Faces.
919  */
920 static BMOpDefine bmo_dissolve_faces_def = {
921         "dissolve_faces",
922         /* slots_in */
923         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
924          {"use_verts", BMO_OP_SLOT_BOOL},  /* dissolve verts left between only 2 edges. */
925          {{'\0'}},
926         },
927         /* slots_out */
928         {{"region.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
929          {{'\0'}},
930         },
931         bmo_dissolve_faces_exec,
932         BMO_OPTYPE_FLAG_UNTAN_MULTIRES | BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
933 };
934
935 /*
936  * Limited Dissolve.
937  *
938  * Dissolve planar faces and co-linear edges.
939  */
940 static BMOpDefine bmo_dissolve_limit_def = {
941         "dissolve_limit",
942         /* slots_in */
943         {{"angle_limit", BMO_OP_SLOT_FLT}, /* total rotation angle (radians) */
944          {"use_dissolve_boundaries", BMO_OP_SLOT_BOOL},
945          {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},
946          {"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
947          {"delimit", BMO_OP_SLOT_INT},
948          {{'\0'}},
949         },
950         {{{'\0'}}},  /* no output */
951         bmo_dissolve_limit_exec,
952         BMO_OPTYPE_FLAG_UNTAN_MULTIRES | BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
953 };
954
955 /*
956  * Triangulate.
957  */
958 static BMOpDefine bmo_triangulate_def = {
959         "triangulate",
960         /* slots_in */
961         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
962          {"use_beauty", BMO_OP_SLOT_BOOL},
963          {{'\0'}},
964         },
965         /* slots_out */
966         {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
967          {"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
968          {"face_map.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
969          {{'\0'}},
970         },
971         bmo_triangulate_exec,
972         BMO_OPTYPE_FLAG_UNTAN_MULTIRES | BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
973 };
974
975 /*
976  * Un-Subdivide.
977  *
978  * Reduce detail in geometry containing grids.
979  */
980 static BMOpDefine bmo_unsubdivide_def = {
981         "unsubdivide",
982         /* slots_in */
983         {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
984          {"iterations", BMO_OP_SLOT_INT},
985          {{'\0'}},
986         },
987         {{{'\0'}}},  /* no output */
988         bmo_unsubdivide_exec,
989         BMO_OPTYPE_FLAG_UNTAN_MULTIRES | BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
990 };
991
992 /*
993  * Subdivide Edges.
994  *
995  * Advanced operator for subdividing edges
996  * with options for face patterns, smoothing and randomization.
997  */
998 static BMOpDefine bmo_subdivide_edges_def = {
999         "subdivide_edges",
1000         /* slots_in */
1001         {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
1002          {"smooth", BMO_OP_SLOT_FLT},
1003          {"smooth_falloff", BMO_OP_SLOT_INT}, /* SUBD_FALLOFF_ROOT and friends */
1004          {"fractal", BMO_OP_SLOT_FLT},
1005          {"along_normal", BMO_OP_SLOT_FLT},
1006          {"cuts", BMO_OP_SLOT_INT},
1007          {"seed", BMO_OP_SLOT_INT},
1008          {"custom_patterns", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL}},  /* uses custom pointers */
1009          {"edge_percents", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_FLT}},
1010
1011          {"quad_corner_type",  BMO_OP_SLOT_INT}, /* quad corner type, see bmesh_operators.h */
1012          {"use_grid_fill", BMO_OP_SLOT_BOOL},   /* fill in fully-selected faces with a grid */
1013          {"use_single_edge", BMO_OP_SLOT_BOOL}, /* tessellate the case of one edge selected in a quad or triangle */
1014          {"use_only_quads", BMO_OP_SLOT_BOOL},  /* only subdivide quads (for loopcut) */
1015          {"use_sphere", BMO_OP_SLOT_BOOL},     /* for making new primitives only */
1016          {"use_smooth_even", BMO_OP_SLOT_BOOL},  /* maintain even offset when smoothing */
1017          {{'\0'}},
1018         },
1019         /* slots_out */
1020         {/* these next three can have multiple types of elements in them */
1021          {"geom_inner.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1022          {"geom_split.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1023          {"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* contains all output geometry */
1024          {{'\0'}},
1025         },
1026         bmo_subdivide_edges_exec,
1027         BMO_OPTYPE_FLAG_UNTAN_MULTIRES | BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
1028 };
1029
1030 /*
1031  * Subdivide Edge-Ring.
1032  *
1033  * Take an edge-ring, and supdivide with interpolation options.
1034  */
1035 static BMOpDefine bmo_subdivide_edgering_def = {
1036         "subdivide_edgering",
1037         /* slots_in */
1038         {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input vertices */
1039          {"interp_mode", BMO_OP_SLOT_INT},
1040          {"smooth", BMO_OP_SLOT_FLT},
1041          {"cuts", BMO_OP_SLOT_INT},
1042          {"profile_shape", BMO_OP_SLOT_INT},
1043          {"profile_shape_factor", BMO_OP_SLOT_FLT},
1044          {{'\0'}},
1045         },
1046         {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
1047          {{'\0'}}},  /* no output */
1048         bmo_subdivide_edgering_exec,
1049         BMO_OPTYPE_FLAG_UNTAN_MULTIRES | BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
1050 };
1051
1052 /*
1053  * Delete Geometry.
1054  *
1055  * Utility operator to delete geometry.
1056  */
1057 static BMOpDefine bmo_delete_def = {
1058         "delete",
1059         /* slots_in */
1060         {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1061          {"context", BMO_OP_SLOT_INT},  /* enum DEL_VERTS ... */
1062          {{'\0'}},
1063         },
1064         {{{'\0'}}},  /* no output */
1065         bmo_delete_exec,
1066         BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
1067 };
1068
1069 /*
1070  * Duplicate Geometry.
1071  *
1072  * Utility operator to duplicate geometry,
1073  * optionally into a destination mesh.
1074  */
1075 static BMOpDefine bmo_duplicate_def = {
1076         "duplicate",
1077         /* slots_in */
1078         {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1079         /* destination bmesh, if NULL will use current on */
1080          {"dest", BMO_OP_SLOT_PTR, {BMO_OP_SLOT_SUBTYPE_PTR_BMESH}},
1081          {{'\0'}},
1082         },
1083         /* slots_out */
1084         {{"geom_orig.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1085          {"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1086         /* facemap maps from source faces to dupe
1087          * faces, and from dupe faces to source faces */
1088          {"face_map.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
1089          {"boundary_map.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
1090          {"isovert_map.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
1091         {{'\0'}},
1092         },
1093         bmo_duplicate_exec,
1094         BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
1095 };
1096
1097 /*
1098  * Split Off Geometry.
1099  *
1100  * Disconnect geometry from adjacent edges and faces,
1101  * optionally into a destination mesh.
1102  */
1103 static BMOpDefine bmo_split_def = {
1104         "split",
1105         /* slots_in */
1106         {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1107         /* destination bmesh, if NULL will use current one */
1108          {"dest", BMO_OP_SLOT_PTR, {BMO_OP_SLOT_SUBTYPE_PTR_BMESH}},
1109          {"use_only_faces", BMO_OP_SLOT_BOOL},  /* when enabled. don't duplicate loose verts/edges */
1110          {{'\0'}},
1111         },
1112         /* slots_out */
1113         {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1114          {"boundary_map.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
1115          {"isovert_map.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
1116          {{'\0'}},
1117         },
1118         bmo_split_exec,
1119         BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
1120 };
1121
1122 /*
1123  * Spin.
1124  *
1125  * Extrude or duplicate geometry a number of times,
1126  * rotating and possibly translating after each step
1127  */
1128 static BMOpDefine bmo_spin_def = {
1129         "spin",
1130         /* slots_in */
1131         {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1132          {"cent", BMO_OP_SLOT_VEC},             /* rotation center */
1133          {"axis", BMO_OP_SLOT_VEC},             /* rotation axis */
1134          {"dvec", BMO_OP_SLOT_VEC},             /* translation delta per step */
1135          {"angle", BMO_OP_SLOT_FLT},            /* total rotation angle (radians) */
1136          {"steps", BMO_OP_SLOT_INT},            /* number of steps */
1137          {"use_duplicate", BMO_OP_SLOT_BOOL},   /* duplicate or extrude? */
1138          {{'\0'}},
1139         },
1140         /* slots_out */
1141         {{"geom_last.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* result of last step */
1142          {{'\0'}},
1143         },
1144         bmo_spin_exec,
1145         BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
1146 };
1147
1148
1149 /*
1150  * Similar Faces Search.
1151  *
1152  * Find similar faces (area/material/perimeter, ...).
1153  */
1154 static BMOpDefine bmo_similar_faces_def = {
1155         "similar_faces",
1156         /* slots_in */
1157         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},    /* input faces */
1158          {"type", BMO_OP_SLOT_INT},             /* type of selection */
1159          {"thresh", BMO_OP_SLOT_FLT},           /* threshold of selection */
1160          {"compare", BMO_OP_SLOT_INT},          /* comparison method */
1161          {{'\0'}},
1162         },
1163         /* slots_out */
1164         {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},  /* output faces */
1165          {{'\0'}},
1166         },
1167         bmo_similar_faces_exec,
1168         BMO_OPTYPE_FLAG_SELECT_FLUSH,
1169 };
1170
1171 /*
1172  * Similar Edges Search.
1173  *
1174  *  Find similar edges (length, direction, edge, seam, ...).
1175  */
1176 static BMOpDefine bmo_similar_edges_def = {
1177         "similar_edges",
1178         /* slots_in */
1179         {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},    /* input edges */
1180          {"type", BMO_OP_SLOT_INT},             /* type of selection */
1181          {"thresh", BMO_OP_SLOT_FLT},           /* threshold of selection */
1182          {"compare", BMO_OP_SLOT_INT},          /* comparison method */
1183          {{'\0'}},
1184         },
1185         /* slots_out */
1186         {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},  /* output edges */
1187          {{'\0'}},
1188         },
1189         bmo_similar_edges_exec,
1190         BMO_OPTYPE_FLAG_SELECT_FLUSH,
1191 };
1192
1193 /*
1194  * Similar Verts Search.
1195  *
1196  * Find similar vertices (normal, face, vertex group, ...).
1197  */
1198 static BMOpDefine bmo_similar_verts_def = {
1199         "similar_verts",
1200         /* slots_in */
1201         {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},    /* input vertices */
1202          {"type", BMO_OP_SLOT_INT},             /* type of selection */
1203          {"thresh", BMO_OP_SLOT_FLT},           /* threshold of selection */
1204          {"compare", BMO_OP_SLOT_INT},          /* comparison method */
1205          {{'\0'}},
1206         },
1207         /* slots_out */
1208         {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},  /* output vertices */
1209          {{'\0'}},
1210         },
1211         bmo_similar_verts_exec,
1212         BMO_OPTYPE_FLAG_SELECT_FLUSH,
1213 };
1214
1215 /*
1216  * UV Rotation.
1217  *
1218  * Cycle the loop UV's
1219  */
1220 static BMOpDefine bmo_rotate_uvs_def = {
1221         "rotate_uvs",
1222         /* slots_in */
1223         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},    /* input faces */
1224          {"use_ccw", BMO_OP_SLOT_BOOL},         /* rotate counter-clockwise if true, otherwise clockwise */
1225          {{'\0'}},
1226         },
1227         /* slots_out */
1228         {{{'\0'}}},  /* no output */
1229         bmo_rotate_uvs_exec,
1230         BMO_OPTYPE_FLAG_NOP,
1231 };
1232
1233 /*
1234  * UV Reverse.
1235  *
1236  * Reverse the UV's
1237  */
1238 static BMOpDefine bmo_reverse_uvs_def = {
1239         "reverse_uvs",
1240         /* slots_in */
1241         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},    /* input faces */
1242          {{'\0'}},
1243         },
1244         {{{'\0'}}},  /* no output */
1245         bmo_reverse_uvs_exec,
1246         BMO_OPTYPE_FLAG_NOP,
1247 };
1248
1249 /*
1250  * Color Rotation.
1251  *
1252  * Cycle the loop colors
1253  */
1254 static BMOpDefine bmo_rotate_colors_def = {
1255         "rotate_colors",
1256         /* slots_in */
1257         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},    /* input faces */
1258          {"use_ccw", BMO_OP_SLOT_BOOL},         /* rotate counter-clockwise if true, otherwise clockwise */
1259          {{'\0'}},
1260         },
1261         {{{'\0'}}},  /* no output */
1262         bmo_rotate_colors_exec,
1263         BMO_OPTYPE_FLAG_NOP,
1264 };
1265
1266 /*
1267  * Color Reverse
1268  *
1269  * Reverse the loop colors.
1270  */
1271 static BMOpDefine bmo_reverse_colors_def = {
1272         "reverse_colors",
1273         /* slots_in */
1274         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},    /* input faces */
1275          {{'\0'}},
1276         },
1277         {{{'\0'}}},  /* no output */
1278         bmo_reverse_colors_exec,
1279         BMO_OPTYPE_FLAG_NOP,
1280 };
1281
1282 /*
1283  * Edge Split.
1284  *
1285  * Disconnects faces along input edges.
1286  */
1287 static BMOpDefine bmo_split_edges_def = {
1288         "split_edges",
1289         /* slots_in */
1290         {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},    /* input edges */
1291          /* needed for vertex rip so we can rip only half an edge at a boundary wich would otherwise split off */
1292          {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},    /* optional tag verts, use to have greater control of splits */
1293          {"use_verts",        BMO_OP_SLOT_BOOL}, /* use 'verts' for splitting, else just find verts to split from edges */
1294          {{'\0'}},
1295         },
1296         /* slots_out */
1297         {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* old output disconnected edges */
1298          {{'\0'}},
1299         },
1300         bmo_split_edges_exec,
1301         BMO_OPTYPE_FLAG_UNTAN_MULTIRES | BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
1302 };
1303
1304 /*
1305  * Create Grid.
1306  *
1307  * Creates a grid with a variable number of subdivisions
1308  */
1309 static BMOpDefine bmo_create_grid_def = {
1310         "create_grid",
1311         /* slots_in */
1312         {{"x_segments",      BMO_OP_SLOT_INT},  /* number of x segments */
1313          {"y_segments",      BMO_OP_SLOT_INT},  /* number of y segments */
1314          {"size",            BMO_OP_SLOT_FLT},  /* size of the grid */
1315          {"matrix",          BMO_OP_SLOT_MAT},  /* matrix to multiply the new geometry with */
1316          {{'\0'}},
1317         },
1318         /* slots_out */
1319         {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
1320          {{'\0'}},
1321         },
1322         bmo_create_grid_exec,
1323         BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
1324 };
1325
1326 /*
1327  * Create UV Sphere.
1328  *
1329  * Creates a grid with a variable number of subdivisions
1330  */
1331 static BMOpDefine bmo_create_uvsphere_def = {
1332         "create_uvsphere",
1333         /* slots_in */
1334         {{"u_segments",      BMO_OP_SLOT_INT}, /* number of u segments */
1335          {"v_segments",      BMO_OP_SLOT_INT}, /* number of v segment */
1336          {"diameter",        BMO_OP_SLOT_FLT}, /* diameter */
1337          {"matrix",          BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */
1338          {{'\0'}},
1339         },
1340         /* slots_out */
1341         {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
1342          {{'\0'}},
1343         },
1344         bmo_create_uvsphere_exec,
1345         BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
1346 };
1347
1348 /*
1349  * Create Ico-Sphere.
1350  *
1351  * Creates a grid with a variable number of subdivisions
1352  */
1353 static BMOpDefine bmo_create_icosphere_def = {
1354         "create_icosphere",
1355         /* slots_in */
1356         {{"subdivisions",    BMO_OP_SLOT_INT}, /* how many times to recursively subdivide the sphere */
1357          {"diameter",        BMO_OP_SLOT_FLT}, /* diameter */
1358          {"matrix",          BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */
1359          {{'\0'}},
1360         },
1361         /* slots_out */
1362         {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
1363          {{'\0'}},
1364         },
1365         bmo_create_icosphere_exec,
1366         BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
1367 };
1368
1369 /*
1370  * Create Suzanne.
1371  *
1372  * Creates a monkey (standard blender primitive).
1373  */
1374 static BMOpDefine bmo_create_monkey_def = {
1375         "create_monkey",
1376         /* slots_in */
1377         {{"matrix", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */
1378          {{'\0'}},
1379         },
1380         /* slots_out */
1381         {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
1382          {{'\0'}},
1383         },
1384         bmo_create_monkey_exec,
1385         BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
1386 };
1387
1388 /*
1389  * Create Cone.
1390  *
1391  * Creates a cone with variable depth at both ends
1392  */
1393 static BMOpDefine bmo_create_cone_def = {
1394         "create_cone",
1395         /* slots_in */
1396         {{"cap_ends",        BMO_OP_SLOT_BOOL},  /* whether or not to fill in the ends with faces */
1397          {"cap_tris",        BMO_OP_SLOT_BOOL},  /* fill ends with triangles instead of ngons */
1398          {"segments",        BMO_OP_SLOT_INT},
1399          {"diameter1",       BMO_OP_SLOT_FLT},  /* diameter of one end */
1400          {"diameter2",       BMO_OP_SLOT_FLT},  /* diameter of the opposite */
1401          {"depth",           BMO_OP_SLOT_FLT},  /* distance between ends */
1402          {"matrix",          BMO_OP_SLOT_MAT},  /* matrix to multiply the new geometry with */
1403          {{'\0'}},
1404         },
1405         /* slots_out */
1406         {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
1407          {{'\0'}},
1408         },
1409         bmo_create_cone_exec,
1410         BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
1411 };
1412
1413 /*
1414  * Creates a Circle.
1415  */
1416 static BMOpDefine bmo_create_circle_def = {
1417         "create_circle",
1418         /* slots_in */
1419         {{"cap_ends",        BMO_OP_SLOT_BOOL},  /* whether or not to fill in the ends with faces */
1420          {"cap_tris",        BMO_OP_SLOT_BOOL},  /* fill ends with triangles instead of ngons */
1421          {"segments",        BMO_OP_SLOT_INT},
1422          {"diameter",        BMO_OP_SLOT_FLT},  /* diameter of one end */
1423          {"matrix",          BMO_OP_SLOT_MAT},  /* matrix to multiply the new geometry with */
1424          {{'\0'}},
1425         },
1426         /* slots_out */
1427         {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
1428          {{'\0'}},
1429         },
1430         bmo_create_circle_exec,
1431         BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
1432 };
1433
1434 /*
1435  * Create Cube
1436  *
1437  * Creates a cube.
1438  */
1439 static BMOpDefine bmo_create_cube_def = {
1440         "create_cube",
1441         /* slots_in */
1442         {{"size",            BMO_OP_SLOT_FLT},  /* size of the cube */
1443          {"matrix",          BMO_OP_SLOT_MAT},  /* matrix to multiply the new geometry with */
1444          {{'\0'}},
1445         },
1446         /* slots_out */
1447         {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
1448          {{'\0'}},
1449         },
1450         bmo_create_cube_exec,
1451         BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
1452 };
1453
1454 /*
1455  * Bevel.
1456  *
1457  * Bevels edges and vertices
1458  */
1459 static BMOpDefine bmo_bevel_def = {
1460         "bevel",
1461         /* slots_in */
1462         {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},     /* input edges and vertices */
1463          {"offset", BMO_OP_SLOT_FLT},           /* amount to offset beveled edge */
1464          {"segments", BMO_OP_SLOT_INT},         /* number of segments in bevel */
1465          {"vertex_only", BMO_OP_SLOT_BOOL},     /* only bevel vertices, not edges */
1466          {{'\0'}},
1467         },
1468         /* slots_out */
1469         {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
1470          {{'\0'}},
1471         },
1472
1473         bmo_bevel_exec,
1474         BMO_OPTYPE_FLAG_UNTAN_MULTIRES | BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
1475 };
1476
1477 /*
1478  * Beautify Fill.
1479  *
1480  * Rotate edges to create more evenly spaced triangles.
1481  */
1482 static BMOpDefine bmo_beautify_fill_def = {
1483         "beautify_fill",
1484         /* slots_in */
1485         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
1486          {"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* edges that can be flipped */
1487          {"use_restrict_tag", BMO_OP_SLOT_BOOL}, /* restrict edge rotation to mixed tagged vertices */
1488          {{'\0'}},
1489         },
1490         /* slots_out */
1491         {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* new flipped faces and edges */
1492          {{'\0'}},
1493         },
1494         bmo_beautify_fill_exec,
1495         BMO_OPTYPE_FLAG_UNTAN_MULTIRES | BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
1496 };
1497
1498 /*
1499  * Triangle Fill.
1500  *
1501  * Fill edges with triangles
1502  */
1503 static BMOpDefine bmo_triangle_fill_def = {
1504         "triangle_fill",
1505         /* slots_in */
1506         {{"use_beauty", BMO_OP_SLOT_BOOL},
1507          {"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},    /* input edges */
1508          {{'\0'}},
1509         },
1510         /* slots_out */
1511         {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* new faces and edges */
1512          {{'\0'}},
1513         },
1514         bmo_triangle_fill_exec,
1515         BMO_OPTYPE_FLAG_UNTAN_MULTIRES | BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
1516 };
1517
1518 /*
1519  * Solidify.
1520  *
1521  * Turns a mesh into a shell with thickness
1522  */
1523 static BMOpDefine bmo_solidify_def = {
1524         "solidify",
1525         /* slots_in */
1526         {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1527          {"thickness", BMO_OP_SLOT_FLT},
1528          {{'\0'}},
1529         },
1530         /* slots_out */
1531         {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1532          {{'\0'}},
1533         },
1534         bmo_solidify_face_region_exec,
1535         BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
1536 };
1537
1538 /*
1539  * Face Inset (Individual).
1540  *
1541  * Insets individual faces.
1542  */
1543 static BMOpDefine bmo_inset_individual_def = {
1544         "inset_individual",
1545         /* slots_in */
1546         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},    /* input faces */
1547          {"thickness", BMO_OP_SLOT_FLT},
1548          {"depth", BMO_OP_SLOT_FLT},
1549          {"use_even_offset", BMO_OP_SLOT_BOOL},
1550          {"use_interpolate", BMO_OP_SLOT_BOOL},
1551          {"use_relative_offset", BMO_OP_SLOT_BOOL},
1552          {{'\0'}},
1553         },
1554         /* slots_out */
1555         {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
1556          {{'\0'}},
1557         },
1558         bmo_inset_individual_exec,
1559         BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
1560 };
1561
1562 /*
1563  * Face Inset (Regions).
1564  *
1565  * Inset or outset face regions.
1566  */
1567 static BMOpDefine bmo_inset_region_def = {
1568         "inset_region",
1569         /* slots_in */
1570         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},    /* input faces */
1571          {"use_boundary", BMO_OP_SLOT_BOOL},
1572          {"use_even_offset", BMO_OP_SLOT_BOOL},
1573          {"use_interpolate", BMO_OP_SLOT_BOOL},
1574          {"use_relative_offset", BMO_OP_SLOT_BOOL},
1575          {"thickness", BMO_OP_SLOT_FLT},
1576          {"depth", BMO_OP_SLOT_FLT},
1577          {"use_outset", BMO_OP_SLOT_BOOL},
1578          {{'\0'}},
1579         },
1580         /* slots_out */
1581         {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
1582          {{'\0'}},
1583         },
1584         bmo_inset_region_exec,
1585         BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
1586 };
1587
1588 /*
1589  * Wire Frame.
1590  *
1591  * Makes a wire-frame copy of faces.
1592  */
1593 static BMOpDefine bmo_wireframe_def = {
1594         "wireframe",
1595         /* slots_in */
1596         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},   /* input faces */
1597          {"use_boundary", BMO_OP_SLOT_BOOL},
1598          {"use_even_offset", BMO_OP_SLOT_BOOL},
1599          {"use_crease", BMO_OP_SLOT_BOOL},
1600          {"thickness", BMO_OP_SLOT_FLT},
1601          {"use_relative_offset", BMO_OP_SLOT_BOOL},
1602          {"depth", BMO_OP_SLOT_FLT},
1603          {{'\0'}},
1604         },
1605         /* slots_out */
1606         {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
1607          {{'\0'}},
1608         },
1609         bmo_wireframe_exec,
1610         BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
1611 };
1612
1613 /*
1614  * Pokes a face.
1615  *
1616  * Splits a face into a triangle fan.
1617  */
1618 static BMOpDefine bmo_poke_def = {
1619         "poke",
1620         /* slots_in */
1621         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},   /* input faces */
1622          {"offset", BMO_OP_SLOT_FLT}, /* center vertex offset along normal */
1623          {"center_mode", BMO_OP_SLOT_INT}, /* calculation mode for center vertex */
1624          {"use_relative_offset", BMO_OP_SLOT_BOOL}, /* apply offset */
1625          {{'\0'}},
1626         },
1627         /* slots_out */
1628         {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
1629          {"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
1630          {{'\0'}},
1631         },
1632         bmo_poke_exec,
1633         BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
1634 };
1635
1636 #ifdef WITH_BULLET
1637 /*
1638  * Convex Hull
1639  *
1640  * Builds a convex hull from the vertices in 'input'.
1641  *
1642  * If 'use_existing_faces' is true, the hull will not output triangles
1643  * that are covered by a pre-existing face.
1644  *
1645  * All hull vertices, faces, and edges are added to 'geom.out'. Any
1646  * input elements that end up inside the hull (i.e. are not used by an
1647  * output face) are added to the 'interior_geom' slot. The
1648  * 'unused_geom' slot will contain all interior geometry that is
1649  * completely unused. Lastly, 'holes_geom' contains edges and faces
1650  * that were in the input and are part of the hull.
1651  */
1652 static BMOpDefine bmo_convex_hull_def = {
1653         "convex_hull",
1654         /* slots_in */
1655         {{"input", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1656          {"use_existing_faces", BMO_OP_SLOT_BOOL},
1657          {{'\0'}},
1658         },
1659         /* slots_out */
1660         {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1661          {"geom_interior.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1662          {"geom_unused.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1663          {"geom_holes.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1664          {{'\0'}},
1665         },
1666         bmo_convex_hull_exec,
1667         BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
1668 };
1669 #endif
1670
1671 /*
1672  * Symmetrize.
1673  *
1674  * Makes the mesh elements in the "input" slot symmetrical. Unlike
1675  * normal mirroring, it only copies in one direction, as specified by
1676  * the "direction" slot. The edges and faces that cross the plane of
1677  * symmetry are split as needed to enforce symmetry.
1678  *
1679  * All new vertices, edges, and faces are added to the "geom.out" slot.
1680  */
1681 static BMOpDefine bmo_symmetrize_def = {
1682         "symmetrize",
1683         /* slots_in */
1684         {{"input", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1685          {"direction", BMO_OP_SLOT_INT},
1686          {{'\0'}},
1687         },
1688         /* slots_out */
1689         {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1690          {{'\0'}},
1691         },
1692         bmo_symmetrize_exec,
1693         BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
1694 };
1695
1696 const BMOpDefine *bmo_opdefines[] = {
1697         &bmo_automerge_def,
1698         &bmo_average_vert_facedata_def,
1699         &bmo_beautify_fill_def,
1700         &bmo_bevel_def,
1701         &bmo_bisect_edges_def,
1702         &bmo_bmesh_to_mesh_def,
1703         &bmo_bridge_loops_def,
1704         &bmo_collapse_def,
1705         &bmo_collapse_uvs_def,
1706         &bmo_connect_verts_def,
1707         &bmo_connect_vert_pair_def,
1708         &bmo_contextual_create_def,
1709 #ifdef WITH_BULLET
1710         &bmo_convex_hull_def,
1711 #endif
1712         &bmo_create_circle_def,
1713         &bmo_create_cone_def,
1714         &bmo_create_cube_def,
1715         &bmo_create_grid_def,
1716         &bmo_create_icosphere_def,
1717         &bmo_create_monkey_def,
1718         &bmo_create_uvsphere_def,
1719         &bmo_create_vert_def,
1720         &bmo_delete_def,
1721         &bmo_dissolve_edges_def,
1722         &bmo_dissolve_faces_def,
1723         &bmo_dissolve_limit_def,
1724         &bmo_dissolve_verts_def,
1725         &bmo_duplicate_def,
1726         &bmo_edgeloop_fill_def,
1727         &bmo_edgenet_fill_def,
1728         &bmo_edgenet_prepare_def,
1729         &bmo_extrude_discrete_faces_def,
1730         &bmo_extrude_edge_only_def,
1731         &bmo_extrude_face_region_def,
1732         &bmo_extrude_vert_indiv_def,
1733         &bmo_find_doubles_def,
1734         &bmo_grid_fill_def,
1735         &bmo_inset_individual_def,
1736         &bmo_inset_region_def,
1737         &bmo_join_triangles_def,
1738         &bmo_mesh_to_bmesh_def,
1739         &bmo_mirror_def,
1740         &bmo_object_load_bmesh_def,
1741         &bmo_pointmerge_def,
1742         &bmo_pointmerge_facedata_def,
1743         &bmo_poke_def,
1744         &bmo_recalc_face_normals_def,
1745         &bmo_region_extend_def,
1746         &bmo_remove_doubles_def,
1747         &bmo_reverse_colors_def,
1748         &bmo_reverse_faces_def,
1749         &bmo_reverse_uvs_def,
1750         &bmo_rotate_colors_def,
1751         &bmo_rotate_def,
1752         &bmo_rotate_edges_def,
1753         &bmo_rotate_uvs_def,
1754         &bmo_scale_def,
1755         &bmo_similar_edges_def,
1756         &bmo_similar_faces_def,
1757         &bmo_similar_verts_def,
1758         &bmo_smooth_vert_def,
1759         &bmo_smooth_laplacian_vert_def,
1760         &bmo_solidify_def,
1761         &bmo_spin_def,
1762         &bmo_split_def,
1763         &bmo_split_edges_def,
1764         &bmo_subdivide_edges_def,
1765         &bmo_subdivide_edgering_def,
1766         &bmo_symmetrize_def,
1767         &bmo_transform_def,
1768         &bmo_translate_def,
1769         &bmo_triangle_fill_def,
1770         &bmo_triangulate_def,
1771         &bmo_unsubdivide_def,
1772         &bmo_weld_verts_def,
1773         &bmo_wireframe_def,
1774 };
1775
1776 const int bmo_opdefines_total = (sizeof(bmo_opdefines) / sizeof(void *));