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