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