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