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