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