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