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