correct problem with limited-dissolve not leaving the selection correctly (caused...
[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         /* slots_out */
951         {{"region.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
952          {{'\0'}}},
953         bmo_dissolve_limit_exec,
954         BMO_OPTYPE_FLAG_UNTAN_MULTIRES | BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
955 };
956
957 /*
958  * Triangulate.
959  */
960 static BMOpDefine bmo_triangulate_def = {
961         "triangulate",
962         /* slots_in */
963         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
964          {"use_beauty", BMO_OP_SLOT_BOOL},
965          {{'\0'}},
966         },
967         /* slots_out */
968         {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
969          {"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
970          {"face_map.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
971          {{'\0'}},
972         },
973         bmo_triangulate_exec,
974         BMO_OPTYPE_FLAG_UNTAN_MULTIRES | BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
975 };
976
977 /*
978  * Un-Subdivide.
979  *
980  * Reduce detail in geometry containing grids.
981  */
982 static BMOpDefine bmo_unsubdivide_def = {
983         "unsubdivide",
984         /* slots_in */
985         {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
986          {"iterations", BMO_OP_SLOT_INT},
987          {{'\0'}},
988         },
989         {{{'\0'}}},  /* no output */
990         bmo_unsubdivide_exec,
991         BMO_OPTYPE_FLAG_UNTAN_MULTIRES | BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
992 };
993
994 /*
995  * Subdivide Edges.
996  *
997  * Advanced operator for subdividing edges
998  * with options for face patterns, smoothing and randomization.
999  */
1000 static BMOpDefine bmo_subdivide_edges_def = {
1001         "subdivide_edges",
1002         /* slots_in */
1003         {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
1004          {"smooth", BMO_OP_SLOT_FLT},
1005          {"smooth_falloff", BMO_OP_SLOT_INT}, /* SUBD_FALLOFF_ROOT and friends */
1006          {"fractal", BMO_OP_SLOT_FLT},
1007          {"along_normal", BMO_OP_SLOT_FLT},
1008          {"cuts", BMO_OP_SLOT_INT},
1009          {"seed", BMO_OP_SLOT_INT},
1010          {"custom_patterns", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL}},  /* uses custom pointers */
1011          {"edge_percents", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_FLT}},
1012
1013          {"quad_corner_type",  BMO_OP_SLOT_INT}, /* quad corner type, see bmesh_operators.h */
1014          {"use_grid_fill", BMO_OP_SLOT_BOOL},   /* fill in fully-selected faces with a grid */
1015          {"use_single_edge", BMO_OP_SLOT_BOOL}, /* tessellate the case of one edge selected in a quad or triangle */
1016          {"use_only_quads", BMO_OP_SLOT_BOOL},  /* only subdivide quads (for loopcut) */
1017          {"use_sphere", BMO_OP_SLOT_BOOL},     /* for making new primitives only */
1018          {"use_smooth_even", BMO_OP_SLOT_BOOL},  /* maintain even offset when smoothing */
1019          {{'\0'}},
1020         },
1021         /* slots_out */
1022         {/* these next three can have multiple types of elements in them */
1023          {"geom_inner.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1024          {"geom_split.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1025          {"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* contains all output geometry */
1026          {{'\0'}},
1027         },
1028         bmo_subdivide_edges_exec,
1029         BMO_OPTYPE_FLAG_UNTAN_MULTIRES | BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
1030 };
1031
1032 /*
1033  * Subdivide Edge-Ring.
1034  *
1035  * Take an edge-ring, and supdivide with interpolation options.
1036  */
1037 static BMOpDefine bmo_subdivide_edgering_def = {
1038         "subdivide_edgering",
1039         /* slots_in */
1040         {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input vertices */
1041          {"interp_mode", BMO_OP_SLOT_INT},
1042          {"smooth", BMO_OP_SLOT_FLT},
1043          {"cuts", BMO_OP_SLOT_INT},
1044          {"profile_shape", BMO_OP_SLOT_INT},
1045          {"profile_shape_factor", BMO_OP_SLOT_FLT},
1046          {{'\0'}},
1047         },
1048         {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
1049          {{'\0'}}},
1050         bmo_subdivide_edgering_exec,
1051         BMO_OPTYPE_FLAG_UNTAN_MULTIRES | BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
1052 };
1053
1054 /*
1055  * Delete Geometry.
1056  *
1057  * Utility operator to delete geometry.
1058  */
1059 static BMOpDefine bmo_delete_def = {
1060         "delete",
1061         /* slots_in */
1062         {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1063          {"context", BMO_OP_SLOT_INT},  /* enum DEL_VERTS ... */
1064          {{'\0'}},
1065         },
1066         {{{'\0'}}},  /* no output */
1067         bmo_delete_exec,
1068         BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
1069 };
1070
1071 /*
1072  * Duplicate Geometry.
1073  *
1074  * Utility operator to duplicate geometry,
1075  * optionally into a destination mesh.
1076  */
1077 static BMOpDefine bmo_duplicate_def = {
1078         "duplicate",
1079         /* slots_in */
1080         {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1081         /* destination bmesh, if NULL will use current on */
1082          {"dest", BMO_OP_SLOT_PTR, {BMO_OP_SLOT_SUBTYPE_PTR_BMESH}},
1083          {{'\0'}},
1084         },
1085         /* slots_out */
1086         {{"geom_orig.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1087          {"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1088         /* facemap maps from source faces to dupe
1089          * faces, and from dupe faces to source faces */
1090          {"face_map.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
1091          {"boundary_map.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
1092          {"isovert_map.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
1093         {{'\0'}},
1094         },
1095         bmo_duplicate_exec,
1096         BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
1097 };
1098
1099 /*
1100  * Split Off Geometry.
1101  *
1102  * Disconnect geometry from adjacent edges and faces,
1103  * optionally into a destination mesh.
1104  */
1105 static BMOpDefine bmo_split_def = {
1106         "split",
1107         /* slots_in */
1108         {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1109         /* destination bmesh, if NULL will use current one */
1110          {"dest", BMO_OP_SLOT_PTR, {BMO_OP_SLOT_SUBTYPE_PTR_BMESH}},
1111          {"use_only_faces", BMO_OP_SLOT_BOOL},  /* when enabled. don't duplicate loose verts/edges */
1112          {{'\0'}},
1113         },
1114         /* slots_out */
1115         {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1116          {"boundary_map.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
1117          {"isovert_map.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
1118          {{'\0'}},
1119         },
1120         bmo_split_exec,
1121         BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
1122 };
1123
1124 /*
1125  * Spin.
1126  *
1127  * Extrude or duplicate geometry a number of times,
1128  * rotating and possibly translating after each step
1129  */
1130 static BMOpDefine bmo_spin_def = {
1131         "spin",
1132         /* slots_in */
1133         {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1134          {"cent", BMO_OP_SLOT_VEC},             /* rotation center */
1135          {"axis", BMO_OP_SLOT_VEC},             /* rotation axis */
1136          {"dvec", BMO_OP_SLOT_VEC},             /* translation delta per step */
1137          {"angle", BMO_OP_SLOT_FLT},            /* total rotation angle (radians) */
1138          {"steps", BMO_OP_SLOT_INT},            /* number of steps */
1139          {"use_duplicate", BMO_OP_SLOT_BOOL},   /* duplicate or extrude? */
1140          {{'\0'}},
1141         },
1142         /* slots_out */
1143         {{"geom_last.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* result of last step */
1144          {{'\0'}},
1145         },
1146         bmo_spin_exec,
1147         BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
1148 };
1149
1150
1151 /*
1152  * Similar Faces Search.
1153  *
1154  * Find similar faces (area/material/perimeter, ...).
1155  */
1156 static BMOpDefine bmo_similar_faces_def = {
1157         "similar_faces",
1158         /* slots_in */
1159         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},    /* input faces */
1160          {"type", BMO_OP_SLOT_INT},             /* type of selection */
1161          {"thresh", BMO_OP_SLOT_FLT},           /* threshold of selection */
1162          {"compare", BMO_OP_SLOT_INT},          /* comparison method */
1163          {{'\0'}},
1164         },
1165         /* slots_out */
1166         {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},  /* output faces */
1167          {{'\0'}},
1168         },
1169         bmo_similar_faces_exec,
1170         BMO_OPTYPE_FLAG_SELECT_FLUSH,
1171 };
1172
1173 /*
1174  * Similar Edges Search.
1175  *
1176  *  Find similar edges (length, direction, edge, seam, ...).
1177  */
1178 static BMOpDefine bmo_similar_edges_def = {
1179         "similar_edges",
1180         /* slots_in */
1181         {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},    /* input edges */
1182          {"type", BMO_OP_SLOT_INT},             /* type of selection */
1183          {"thresh", BMO_OP_SLOT_FLT},           /* threshold of selection */
1184          {"compare", BMO_OP_SLOT_INT},          /* comparison method */
1185          {{'\0'}},
1186         },
1187         /* slots_out */
1188         {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},  /* output edges */
1189          {{'\0'}},
1190         },
1191         bmo_similar_edges_exec,
1192         BMO_OPTYPE_FLAG_SELECT_FLUSH,
1193 };
1194
1195 /*
1196  * Similar Verts Search.
1197  *
1198  * Find similar vertices (normal, face, vertex group, ...).
1199  */
1200 static BMOpDefine bmo_similar_verts_def = {
1201         "similar_verts",
1202         /* slots_in */
1203         {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},    /* input vertices */
1204          {"type", BMO_OP_SLOT_INT},             /* type of selection */
1205          {"thresh", BMO_OP_SLOT_FLT},           /* threshold of selection */
1206          {"compare", BMO_OP_SLOT_INT},          /* comparison method */
1207          {{'\0'}},
1208         },
1209         /* slots_out */
1210         {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},  /* output vertices */
1211          {{'\0'}},
1212         },
1213         bmo_similar_verts_exec,
1214         BMO_OPTYPE_FLAG_SELECT_FLUSH,
1215 };
1216
1217 /*
1218  * UV Rotation.
1219  *
1220  * Cycle the loop UV's
1221  */
1222 static BMOpDefine bmo_rotate_uvs_def = {
1223         "rotate_uvs",
1224         /* slots_in */
1225         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},    /* input faces */
1226          {"use_ccw", BMO_OP_SLOT_BOOL},         /* rotate counter-clockwise if true, otherwise clockwise */
1227          {{'\0'}},
1228         },
1229         {{{'\0'}}},  /* no output */
1230         bmo_rotate_uvs_exec,
1231         BMO_OPTYPE_FLAG_NOP,
1232 };
1233
1234 /*
1235  * UV Reverse.
1236  *
1237  * Reverse the UV's
1238  */
1239 static BMOpDefine bmo_reverse_uvs_def = {
1240         "reverse_uvs",
1241         /* slots_in */
1242         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},    /* input faces */
1243          {{'\0'}},
1244         },
1245         {{{'\0'}}},  /* no output */
1246         bmo_reverse_uvs_exec,
1247         BMO_OPTYPE_FLAG_NOP,
1248 };
1249
1250 /*
1251  * Color Rotation.
1252  *
1253  * Cycle the loop colors
1254  */
1255 static BMOpDefine bmo_rotate_colors_def = {
1256         "rotate_colors",
1257         /* slots_in */
1258         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},    /* input faces */
1259          {"use_ccw", BMO_OP_SLOT_BOOL},         /* rotate counter-clockwise if true, otherwise clockwise */
1260          {{'\0'}},
1261         },
1262         {{{'\0'}}},  /* no output */
1263         bmo_rotate_colors_exec,
1264         BMO_OPTYPE_FLAG_NOP,
1265 };
1266
1267 /*
1268  * Color Reverse
1269  *
1270  * Reverse the loop colors.
1271  */
1272 static BMOpDefine bmo_reverse_colors_def = {
1273         "reverse_colors",
1274         /* slots_in */
1275         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},    /* input faces */
1276          {{'\0'}},
1277         },
1278         {{{'\0'}}},  /* no output */
1279         bmo_reverse_colors_exec,
1280         BMO_OPTYPE_FLAG_NOP,
1281 };
1282
1283 /*
1284  * Edge Split.
1285  *
1286  * Disconnects faces along input edges.
1287  */
1288 static BMOpDefine bmo_split_edges_def = {
1289         "split_edges",
1290         /* slots_in */
1291         {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},    /* input edges */
1292          /* needed for vertex rip so we can rip only half an edge at a boundary wich would otherwise split off */
1293          {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},    /* optional tag verts, use to have greater control of splits */
1294          {"use_verts",        BMO_OP_SLOT_BOOL}, /* use 'verts' for splitting, else just find verts to split from edges */
1295          {{'\0'}},
1296         },
1297         /* slots_out */
1298         {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* old output disconnected edges */
1299          {{'\0'}},
1300         },
1301         bmo_split_edges_exec,
1302         BMO_OPTYPE_FLAG_UNTAN_MULTIRES | BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
1303 };
1304
1305 /*
1306  * Create Grid.
1307  *
1308  * Creates a grid with a variable number of subdivisions
1309  */
1310 static BMOpDefine bmo_create_grid_def = {
1311         "create_grid",
1312         /* slots_in */
1313         {{"x_segments",      BMO_OP_SLOT_INT},  /* number of x segments */
1314          {"y_segments",      BMO_OP_SLOT_INT},  /* number of y segments */
1315          {"size",            BMO_OP_SLOT_FLT},  /* size of the grid */
1316          {"matrix",          BMO_OP_SLOT_MAT},  /* matrix to multiply the new geometry with */
1317          {{'\0'}},
1318         },
1319         /* slots_out */
1320         {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
1321          {{'\0'}},
1322         },
1323         bmo_create_grid_exec,
1324         BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
1325 };
1326
1327 /*
1328  * Create UV Sphere.
1329  *
1330  * Creates a grid with a variable number of subdivisions
1331  */
1332 static BMOpDefine bmo_create_uvsphere_def = {
1333         "create_uvsphere",
1334         /* slots_in */
1335         {{"u_segments",      BMO_OP_SLOT_INT}, /* number of u segments */
1336          {"v_segments",      BMO_OP_SLOT_INT}, /* number of v segment */
1337          {"diameter",        BMO_OP_SLOT_FLT}, /* diameter */
1338          {"matrix",          BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */
1339          {{'\0'}},
1340         },
1341         /* slots_out */
1342         {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
1343          {{'\0'}},
1344         },
1345         bmo_create_uvsphere_exec,
1346         BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
1347 };
1348
1349 /*
1350  * Create Ico-Sphere.
1351  *
1352  * Creates a grid with a variable number of subdivisions
1353  */
1354 static BMOpDefine bmo_create_icosphere_def = {
1355         "create_icosphere",
1356         /* slots_in */
1357         {{"subdivisions",    BMO_OP_SLOT_INT}, /* how many times to recursively subdivide the sphere */
1358          {"diameter",        BMO_OP_SLOT_FLT}, /* diameter */
1359          {"matrix",          BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */
1360          {{'\0'}},
1361         },
1362         /* slots_out */
1363         {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
1364          {{'\0'}},
1365         },
1366         bmo_create_icosphere_exec,
1367         BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
1368 };
1369
1370 /*
1371  * Create Suzanne.
1372  *
1373  * Creates a monkey (standard blender primitive).
1374  */
1375 static BMOpDefine bmo_create_monkey_def = {
1376         "create_monkey",
1377         /* slots_in */
1378         {{"matrix", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */
1379          {{'\0'}},
1380         },
1381         /* slots_out */
1382         {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
1383          {{'\0'}},
1384         },
1385         bmo_create_monkey_exec,
1386         BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
1387 };
1388
1389 /*
1390  * Create Cone.
1391  *
1392  * Creates a cone with variable depth at both ends
1393  */
1394 static BMOpDefine bmo_create_cone_def = {
1395         "create_cone",
1396         /* slots_in */
1397         {{"cap_ends",        BMO_OP_SLOT_BOOL},  /* whether or not to fill in the ends with faces */
1398          {"cap_tris",        BMO_OP_SLOT_BOOL},  /* fill ends with triangles instead of ngons */
1399          {"segments",        BMO_OP_SLOT_INT},
1400          {"diameter1",       BMO_OP_SLOT_FLT},  /* diameter of one end */
1401          {"diameter2",       BMO_OP_SLOT_FLT},  /* diameter of the opposite */
1402          {"depth",           BMO_OP_SLOT_FLT},  /* distance between ends */
1403          {"matrix",          BMO_OP_SLOT_MAT},  /* matrix to multiply the new geometry with */
1404          {{'\0'}},
1405         },
1406         /* slots_out */
1407         {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
1408          {{'\0'}},
1409         },
1410         bmo_create_cone_exec,
1411         BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
1412 };
1413
1414 /*
1415  * Creates a Circle.
1416  */
1417 static BMOpDefine bmo_create_circle_def = {
1418         "create_circle",
1419         /* slots_in */
1420         {{"cap_ends",        BMO_OP_SLOT_BOOL},  /* whether or not to fill in the ends with faces */
1421          {"cap_tris",        BMO_OP_SLOT_BOOL},  /* fill ends with triangles instead of ngons */
1422          {"segments",        BMO_OP_SLOT_INT},
1423          {"diameter",        BMO_OP_SLOT_FLT},  /* diameter of one end */
1424          {"matrix",          BMO_OP_SLOT_MAT},  /* matrix to multiply the new geometry with */
1425          {{'\0'}},
1426         },
1427         /* slots_out */
1428         {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
1429          {{'\0'}},
1430         },
1431         bmo_create_circle_exec,
1432         BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
1433 };
1434
1435 /*
1436  * Create Cube
1437  *
1438  * Creates a cube.
1439  */
1440 static BMOpDefine bmo_create_cube_def = {
1441         "create_cube",
1442         /* slots_in */
1443         {{"size",            BMO_OP_SLOT_FLT},  /* size of the cube */
1444          {"matrix",          BMO_OP_SLOT_MAT},  /* matrix to multiply the new geometry with */
1445          {{'\0'}},
1446         },
1447         /* slots_out */
1448         {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
1449          {{'\0'}},
1450         },
1451         bmo_create_cube_exec,
1452         BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
1453 };
1454
1455 /*
1456  * Bevel.
1457  *
1458  * Bevels edges and vertices
1459  */
1460 static BMOpDefine bmo_bevel_def = {
1461         "bevel",
1462         /* slots_in */
1463         {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},     /* input edges and vertices */
1464          {"offset", BMO_OP_SLOT_FLT},           /* amount to offset beveled edge */
1465          {"segments", BMO_OP_SLOT_INT},         /* number of segments in bevel */
1466          {"vertex_only", BMO_OP_SLOT_BOOL},     /* only bevel vertices, not edges */
1467          {{'\0'}},
1468         },
1469         /* slots_out */
1470         {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
1471          {{'\0'}},
1472         },
1473
1474         bmo_bevel_exec,
1475         BMO_OPTYPE_FLAG_UNTAN_MULTIRES | BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
1476 };
1477
1478 /*
1479  * Beautify Fill.
1480  *
1481  * Rotate edges to create more evenly spaced triangles.
1482  */
1483 static BMOpDefine bmo_beautify_fill_def = {
1484         "beautify_fill",
1485         /* slots_in */
1486         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
1487          {"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* edges that can be flipped */
1488          {"use_restrict_tag", BMO_OP_SLOT_BOOL}, /* restrict edge rotation to mixed tagged vertices */
1489          {{'\0'}},
1490         },
1491         /* slots_out */
1492         {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* new flipped faces and edges */
1493          {{'\0'}},
1494         },
1495         bmo_beautify_fill_exec,
1496         BMO_OPTYPE_FLAG_UNTAN_MULTIRES | BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
1497 };
1498
1499 /*
1500  * Triangle Fill.
1501  *
1502  * Fill edges with triangles
1503  */
1504 static BMOpDefine bmo_triangle_fill_def = {
1505         "triangle_fill",
1506         /* slots_in */
1507         {{"use_beauty", BMO_OP_SLOT_BOOL},
1508          {"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},    /* input edges */
1509          {{'\0'}},
1510         },
1511         /* slots_out */
1512         {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* new faces and edges */
1513          {{'\0'}},
1514         },
1515         bmo_triangle_fill_exec,
1516         BMO_OPTYPE_FLAG_UNTAN_MULTIRES | BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
1517 };
1518
1519 /*
1520  * Solidify.
1521  *
1522  * Turns a mesh into a shell with thickness
1523  */
1524 static BMOpDefine bmo_solidify_def = {
1525         "solidify",
1526         /* slots_in */
1527         {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1528          {"thickness", BMO_OP_SLOT_FLT},
1529          {{'\0'}},
1530         },
1531         /* slots_out */
1532         {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1533          {{'\0'}},
1534         },
1535         bmo_solidify_face_region_exec,
1536         BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
1537 };
1538
1539 /*
1540  * Face Inset (Individual).
1541  *
1542  * Insets individual faces.
1543  */
1544 static BMOpDefine bmo_inset_individual_def = {
1545         "inset_individual",
1546         /* slots_in */
1547         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},    /* input faces */
1548          {"thickness", BMO_OP_SLOT_FLT},
1549          {"depth", BMO_OP_SLOT_FLT},
1550          {"use_even_offset", BMO_OP_SLOT_BOOL},
1551          {"use_interpolate", BMO_OP_SLOT_BOOL},
1552          {"use_relative_offset", BMO_OP_SLOT_BOOL},
1553          {{'\0'}},
1554         },
1555         /* slots_out */
1556         {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
1557          {{'\0'}},
1558         },
1559         bmo_inset_individual_exec,
1560         BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
1561 };
1562
1563 /*
1564  * Face Inset (Regions).
1565  *
1566  * Inset or outset face regions.
1567  */
1568 static BMOpDefine bmo_inset_region_def = {
1569         "inset_region",
1570         /* slots_in */
1571         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},    /* input faces */
1572          {"use_boundary", BMO_OP_SLOT_BOOL},
1573          {"use_even_offset", BMO_OP_SLOT_BOOL},
1574          {"use_interpolate", BMO_OP_SLOT_BOOL},
1575          {"use_relative_offset", BMO_OP_SLOT_BOOL},
1576          {"thickness", BMO_OP_SLOT_FLT},
1577          {"depth", BMO_OP_SLOT_FLT},
1578          {"use_outset", BMO_OP_SLOT_BOOL},
1579          {{'\0'}},
1580         },
1581         /* slots_out */
1582         {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
1583          {{'\0'}},
1584         },
1585         bmo_inset_region_exec,
1586         BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
1587 };
1588
1589 /*
1590  * Wire Frame.
1591  *
1592  * Makes a wire-frame copy of faces.
1593  */
1594 static BMOpDefine bmo_wireframe_def = {
1595         "wireframe",
1596         /* slots_in */
1597         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},   /* input faces */
1598          {"use_boundary", BMO_OP_SLOT_BOOL},
1599          {"use_even_offset", BMO_OP_SLOT_BOOL},
1600          {"use_crease", BMO_OP_SLOT_BOOL},
1601          {"thickness", BMO_OP_SLOT_FLT},
1602          {"use_relative_offset", BMO_OP_SLOT_BOOL},
1603          {"depth", BMO_OP_SLOT_FLT},
1604          {{'\0'}},
1605         },
1606         /* slots_out */
1607         {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
1608          {{'\0'}},
1609         },
1610         bmo_wireframe_exec,
1611         BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
1612 };
1613
1614 /*
1615  * Pokes a face.
1616  *
1617  * Splits a face into a triangle fan.
1618  */
1619 static BMOpDefine bmo_poke_def = {
1620         "poke",
1621         /* slots_in */
1622         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},   /* input faces */
1623          {"offset", BMO_OP_SLOT_FLT}, /* center vertex offset along normal */
1624          {"center_mode", BMO_OP_SLOT_INT}, /* calculation mode for center vertex */
1625          {"use_relative_offset", BMO_OP_SLOT_BOOL}, /* apply offset */
1626          {{'\0'}},
1627         },
1628         /* slots_out */
1629         {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
1630          {"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
1631          {{'\0'}},
1632         },
1633         bmo_poke_exec,
1634         BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
1635 };
1636
1637 #ifdef WITH_BULLET
1638 /*
1639  * Convex Hull
1640  *
1641  * Builds a convex hull from the vertices in 'input'.
1642  *
1643  * If 'use_existing_faces' is true, the hull will not output triangles
1644  * that are covered by a pre-existing face.
1645  *
1646  * All hull vertices, faces, and edges are added to 'geom.out'. Any
1647  * input elements that end up inside the hull (i.e. are not used by an
1648  * output face) are added to the 'interior_geom' slot. The
1649  * 'unused_geom' slot will contain all interior geometry that is
1650  * completely unused. Lastly, 'holes_geom' contains edges and faces
1651  * that were in the input and are part of the hull.
1652  */
1653 static BMOpDefine bmo_convex_hull_def = {
1654         "convex_hull",
1655         /* slots_in */
1656         {{"input", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1657          {"use_existing_faces", BMO_OP_SLOT_BOOL},
1658          {{'\0'}},
1659         },
1660         /* slots_out */
1661         {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1662          {"geom_interior.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1663          {"geom_unused.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1664          {"geom_holes.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1665          {{'\0'}},
1666         },
1667         bmo_convex_hull_exec,
1668         BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
1669 };
1670 #endif
1671
1672 /*
1673  * Symmetrize.
1674  *
1675  * Makes the mesh elements in the "input" slot symmetrical. Unlike
1676  * normal mirroring, it only copies in one direction, as specified by
1677  * the "direction" slot. The edges and faces that cross the plane of
1678  * symmetry are split as needed to enforce symmetry.
1679  *
1680  * All new vertices, edges, and faces are added to the "geom.out" slot.
1681  */
1682 static BMOpDefine bmo_symmetrize_def = {
1683         "symmetrize",
1684         /* slots_in */
1685         {{"input", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1686          {"direction", BMO_OP_SLOT_INT},
1687          {{'\0'}},
1688         },
1689         /* slots_out */
1690         {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1691          {{'\0'}},
1692         },
1693         bmo_symmetrize_exec,
1694         BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
1695 };
1696
1697 const BMOpDefine *bmo_opdefines[] = {
1698         &bmo_automerge_def,
1699         &bmo_average_vert_facedata_def,
1700         &bmo_beautify_fill_def,
1701         &bmo_bevel_def,
1702         &bmo_bisect_edges_def,
1703         &bmo_bmesh_to_mesh_def,
1704         &bmo_bridge_loops_def,
1705         &bmo_collapse_def,
1706         &bmo_collapse_uvs_def,
1707         &bmo_connect_verts_def,
1708         &bmo_connect_vert_pair_def,
1709         &bmo_contextual_create_def,
1710 #ifdef WITH_BULLET
1711         &bmo_convex_hull_def,
1712 #endif
1713         &bmo_create_circle_def,
1714         &bmo_create_cone_def,
1715         &bmo_create_cube_def,
1716         &bmo_create_grid_def,
1717         &bmo_create_icosphere_def,
1718         &bmo_create_monkey_def,
1719         &bmo_create_uvsphere_def,
1720         &bmo_create_vert_def,
1721         &bmo_delete_def,
1722         &bmo_dissolve_edges_def,
1723         &bmo_dissolve_faces_def,
1724         &bmo_dissolve_limit_def,
1725         &bmo_dissolve_verts_def,
1726         &bmo_duplicate_def,
1727         &bmo_edgeloop_fill_def,
1728         &bmo_edgenet_fill_def,
1729         &bmo_edgenet_prepare_def,
1730         &bmo_extrude_discrete_faces_def,
1731         &bmo_extrude_edge_only_def,
1732         &bmo_extrude_face_region_def,
1733         &bmo_extrude_vert_indiv_def,
1734         &bmo_find_doubles_def,
1735         &bmo_grid_fill_def,
1736         &bmo_inset_individual_def,
1737         &bmo_inset_region_def,
1738         &bmo_join_triangles_def,
1739         &bmo_mesh_to_bmesh_def,
1740         &bmo_mirror_def,
1741         &bmo_object_load_bmesh_def,
1742         &bmo_pointmerge_def,
1743         &bmo_pointmerge_facedata_def,
1744         &bmo_poke_def,
1745         &bmo_recalc_face_normals_def,
1746         &bmo_region_extend_def,
1747         &bmo_remove_doubles_def,
1748         &bmo_reverse_colors_def,
1749         &bmo_reverse_faces_def,
1750         &bmo_reverse_uvs_def,
1751         &bmo_rotate_colors_def,
1752         &bmo_rotate_def,
1753         &bmo_rotate_edges_def,
1754         &bmo_rotate_uvs_def,
1755         &bmo_scale_def,
1756         &bmo_similar_edges_def,
1757         &bmo_similar_faces_def,
1758         &bmo_similar_verts_def,
1759         &bmo_smooth_vert_def,
1760         &bmo_smooth_laplacian_vert_def,
1761         &bmo_solidify_def,
1762         &bmo_spin_def,
1763         &bmo_split_def,
1764         &bmo_split_edges_def,
1765         &bmo_subdivide_edges_def,
1766         &bmo_subdivide_edgering_def,
1767         &bmo_symmetrize_def,
1768         &bmo_transform_def,
1769         &bmo_translate_def,
1770         &bmo_triangle_fill_def,
1771         &bmo_triangulate_def,
1772         &bmo_unsubdivide_def,
1773         &bmo_weld_verts_def,
1774         &bmo_wireframe_def,
1775 };
1776
1777 const int bmo_opdefines_total = (sizeof(bmo_opdefines) / sizeof(void *));