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