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