bmesh inset: add depth option (make use of relative and even offset 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_vertexsmooth_def = {
101         "vertexsmooth",
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_vertexsmooth_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_righthandfaces_def = {
120         "righthandfaces",
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_righthandfaces_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_regionextend_def = {
140         "regionextend",
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_regionextend_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_edgerotate_def = {
158         "edgerotate",
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_edgerotate_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_reversefaces_def = {
175         "reversefaces",
176         {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, //input faces
177          {0} /* null-terminating sentinel */,
178         },
179         bmo_reversefaces_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_edgebisect_def = {
190         "edgebisect",
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_edgebisect_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 keepverts is used, vertices outside that set can only be merged
229  * with vertices in that set.
230  */
231 static BMOpDefine bmo_finddoubles_def = {
232         "finddoubles",
233         {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, //input vertices
234          {BMO_OP_SLOT_ELEMENT_BUF, "keepverts"}, //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_finddoubles_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_removedoubles_def = {
249         "removedoubles",
250         {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, //input verts
251          {BMO_OP_SLOT_FLT,         "dist"}, //minimum distance
252          {0, /* null-terminating sentinel */}},
253         bmo_removedoubles_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_vert_average_facedata_def = {
309         "vert_average_facedata",
310         {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertice */
311          {0, /* null-terminating sentinel */}},
312         bmo_vert_average_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,         "mergeco"},
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_weldverts_def = {
351         "weldverts",
352         {{BMO_OP_SLOT_MAPPING, "targetmap"}, /* maps welded vertices to verts they should weld to */
353          {0, /* null-terminating sentinel */}},
354         bmo_weldverts_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_makevert_def = {
365         "makevert",
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_makevert_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          {0, /* null-terminating sentinel */}},
410         bmo_contextual_create_exec,
411         BMO_OP_FLAG_UNTAN_MULTIRES,
412 };
413
414 /*
415  * Bridge edge loops with faces
416  */
417 static BMOpDefine bmo_bridge_loops_def = {
418         "bridge_loops",
419         {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edge */
420          {BMO_OP_SLOT_ELEMENT_BUF, "faceout"}, /* new face */
421          {0, /* null-terminating sentinel */}},
422         bmo_bridge_loops_exec,
423         0,
424 };
425
426 static BMOpDefine bmo_edgenet_fill_def = {
427         "edgenet_fill",
428         {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edge */
429          {BMO_OP_SLOT_MAPPING,     "restrict"}, /* restricts edges to groups.  maps edges to integer */
430          {BMO_OP_SLOT_BOOL,        "use_restrict"},
431          {BMO_OP_SLOT_BOOL,        "use_fill_check"},
432          {BMO_OP_SLOT_ELEMENT_BUF, "excludefaces"}, /* list of faces to ignore for manifold check */
433          {BMO_OP_SLOT_MAPPING,     "faceout_groupmap"}, /* maps new faces to the group numbers they came fro */
434          {BMO_OP_SLOT_ELEMENT_BUF, "faceout"}, /* new face */
435          {BMO_OP_SLOT_INT,         "mat_nr"},  /* material to use */
436          {0, /* null-terminating sentinel */}},
437         bmo_edgenet_fill_exec,
438         0,
439 };
440
441 /*
442  * Edgenet Prepare
443  *
444  * Identifies several useful edge loop cases and modifies them so
445  * they'll become a face when edgenet_fill is called.  The cases covered are:
446  *
447  * - One single loop; an edge is added to connect the ends
448  * - Two loops; two edges are added to connect the endpoints (based on the
449  *   shortest distance between each endpont).
450  */
451 static BMOpDefine bmo_edgenet_prepare_def = {
452         "edgenet_prepare",
453         {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, //input edges
454          {BMO_OP_SLOT_ELEMENT_BUF, "edgeout"}, //new edges
455          {0, /* null-terminating sentinel */}},
456         bmo_edgenet_prepare,
457         0,
458 };
459
460 /*
461  * Rotate
462  *
463  * Rotate vertices around a center, using a 3x3 rotation
464  * matrix.  Equivalent of the old rotateflag function.
465  */
466 static BMOpDefine bmo_rotate_def = {
467         "rotate",
468         {{BMO_OP_SLOT_VEC, "cent"}, //center of rotation
469          {BMO_OP_SLOT_MAT, "mat"}, //matrix defining rotation
470          {BMO_OP_SLOT_ELEMENT_BUF, "verts"}, //input vertices
471          {0, /* null-terminating sentinel */}},
472         bmo_rotate_exec,
473         0,
474 };
475
476 /*
477  * Translate
478  *
479  * Translate vertices by an offset.  Equivalent of the
480  * old translateflag function.
481  */
482 static BMOpDefine bmo_translate_def = {
483         "translate",
484         {{BMO_OP_SLOT_VEC, "vec"}, //translation offset
485          {BMO_OP_SLOT_ELEMENT_BUF, "verts"}, //input vertices
486          {0, /* null-terminating sentinel */}},
487         bmo_translate_exec,
488         0,
489 };
490
491 /*
492  * Scale
493  *
494  * Scales vertices by an offset.
495  */
496 static BMOpDefine bmo_scale_def = {
497         "scale",
498         {{BMO_OP_SLOT_VEC, "vec"}, //scale factor
499          {BMO_OP_SLOT_ELEMENT_BUF, "verts"}, //input vertices
500          {0, /* null-terminating sentinel */}},
501         bmo_scale_exec,
502         0,
503 };
504
505
506 /*
507  * Transform
508  *
509  * Transforms a set of vertices by a matrix.  Multiplies
510  * the vertex coordinates with the matrix.
511  */
512 static BMOpDefine bmo_transform_def = {
513         "transform",
514         {{BMO_OP_SLOT_MAT, "mat"}, //transform matrix
515          {BMO_OP_SLOT_ELEMENT_BUF, "verts"}, //input vertices
516          {0, /* null-terminating sentinel */}},
517         bmo_transform_exec,
518         0,
519 };
520
521 /*
522  * Object Load BMesh
523  *
524  * Loads a bmesh into an object/mesh.  This is a "private"
525  * bmop.
526  */
527 static BMOpDefine bmo_object_load_bmesh_def = {
528         "object_load_bmesh",
529         {{BMO_OP_SLOT_PNT, "scene"},
530          {BMO_OP_SLOT_PNT, "object"},
531          {0, /* null-terminating sentinel */}},
532         bmo_object_load_bmesh_exec,
533         0,
534 };
535
536
537 /*
538  * BMesh to Mesh
539  *
540  * Converts a bmesh to a Mesh.  This is reserved for exiting editmode.
541  */
542 static BMOpDefine bmo_bmesh_to_mesh_def = {
543         "bmesh_to_mesh",
544         {{BMO_OP_SLOT_PNT, "mesh"}, //pointer to a mesh structure to fill in
545          {BMO_OP_SLOT_PNT, "object"}, //pointer to an object structure
546          {BMO_OP_SLOT_BOOL, "notessellation"}, //don't calculate mfaces
547          {0, /* null-terminating sentinel */}},
548         bmo_bmesh_to_mesh_exec,
549         0,
550 };
551
552 /*
553  * Mesh to BMesh
554  *
555  * Load the contents of a mesh into the bmesh.  this bmop is private, it's
556  * reserved exclusively for entering editmode.
557  */
558 static BMOpDefine bmo_mesh_to_bmesh_def = {
559         "mesh_to_bmesh",
560         {{BMO_OP_SLOT_PNT, "mesh"}, //pointer to a Mesh structure
561          {BMO_OP_SLOT_PNT, "object"}, //pointer to an Object structure
562          {BMO_OP_SLOT_BOOL, "set_shapekey"}, //load active shapekey coordinates into verts
563          {0, /* null-terminating sentinel */}},
564         bmo_mesh_to_bmesh_exec,
565         0
566 };
567
568 /*
569  * Individual Face Extrude
570  *
571  * Extrudes faces individually.
572  */
573 static BMOpDefine bmo_extrude_indivface_def = {
574         "extrude_face_indiv",
575         {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, //input faces
576          {BMO_OP_SLOT_ELEMENT_BUF, "faceout"}, //output faces
577          {BMO_OP_SLOT_ELEMENT_BUF, "skirtout"}, //output skirt geometry, faces and edges
578          {0} /* null-terminating sentinel */},
579         bmo_extrude_face_indiv_exec,
580         0
581 };
582
583 /*
584  * Extrude Only Edges
585  *
586  * Extrudes Edges into faces, note that this is very simple, there's no fancy
587  * winged extrusion.
588  */
589 static BMOpDefine bmo_extrude_edge_only_def = {
590         "extrude_edge_only",
591         {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, //input vertices
592          {BMO_OP_SLOT_ELEMENT_BUF, "geomout"}, //output geometry
593          {0} /* null-terminating sentinel */},
594         bmo_extrude_edge_only_exec,
595         0
596 };
597
598 /*
599  * Individual Vertex Extrude
600  *
601  * Extrudes wire edges from vertices.
602  */
603 static BMOpDefine bmo_extrude_vert_indiv_def = {
604         "extrude_vert_indiv",
605         {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, //input vertices
606          {BMO_OP_SLOT_ELEMENT_BUF, "edgeout"}, //output wire edges
607          {BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, //output vertices
608          {0} /* null-terminating sentinel */},
609         bmo_extrude_vert_indiv_exec,
610         0
611 };
612
613 static BMOpDefine bmo_connectverts_def = {
614         "connectverts",
615         {{BMO_OP_SLOT_ELEMENT_BUF, "verts"},
616          {BMO_OP_SLOT_ELEMENT_BUF, "edgeout"},
617          {0} /* null-terminating sentinel */},
618         bmo_connectverts_exec,
619         BMO_OP_FLAG_UNTAN_MULTIRES
620 };
621
622 static BMOpDefine bmo_extrude_face_region_def = {
623         "extrude_face_region",
624         {{BMO_OP_SLOT_ELEMENT_BUF, "edgefacein"},
625          {BMO_OP_SLOT_MAPPING, "exclude"},
626          {BMO_OP_SLOT_BOOL, "alwayskeeporig"},
627          {BMO_OP_SLOT_ELEMENT_BUF, "geomout"},
628          {0} /* null-terminating sentinel */},
629         bmo_extrude_face_region_exec,
630         0
631 };
632
633 static BMOpDefine bmo_dissolve_verts_def = {
634         "dissolve_verts",
635         {{BMO_OP_SLOT_ELEMENT_BUF, "verts"},
636          {0} /* null-terminating sentinel */},
637         bmo_dissolve_verts_exec,
638         BMO_OP_FLAG_UNTAN_MULTIRES
639 };
640
641 static BMOpDefine bmo_dissolve_edges_def = {
642         "dissolve_edges",
643         {{BMO_OP_SLOT_ELEMENT_BUF, "edges"},
644          {BMO_OP_SLOT_ELEMENT_BUF, "regionout"},
645          {BMO_OP_SLOT_BOOL, "use_verts"}, // dissolve verts left between only 2 edges.
646          {0} /* null-terminating sentinel */},
647         bmo_dissolve_edges_exec,
648         BMO_OP_FLAG_UNTAN_MULTIRES
649 };
650
651 static BMOpDefine bmo_dissolve_edge_loop_def = {
652         "dissolve_edge_loop",
653         {{BMO_OP_SLOT_ELEMENT_BUF, "edges"},
654          {BMO_OP_SLOT_ELEMENT_BUF, "regionout"},
655          {0} /* null-terminating sentinel */},
656         bmo_dissolve_edgeloop_exec,
657         BMO_OP_FLAG_UNTAN_MULTIRES
658 };
659
660 static BMOpDefine bmo_dissolve_faces_def = {
661         "dissolve_faces",
662         {{BMO_OP_SLOT_ELEMENT_BUF, "faces"},
663          {BMO_OP_SLOT_ELEMENT_BUF, "regionout"},
664          {BMO_OP_SLOT_BOOL, "use_verts"}, // dissolve verts left between only 2 edges.
665          {0} /* null-terminating sentinel */},
666         bmo_dissolve_faces_exec,
667         BMO_OP_FLAG_UNTAN_MULTIRES
668 };
669
670 static BMOpDefine bmo_dissolve_limit_def = {
671         "dissolve_limit",
672         {{BMO_OP_SLOT_FLT, "angle_limit"}, /* total rotation angle (degrees) */
673          {BMO_OP_SLOT_ELEMENT_BUF, "verts"},
674          {BMO_OP_SLOT_ELEMENT_BUF, "edges"},
675          {0} /* null-terminating sentinel */},
676         bmo_dissolve_limit_exec,
677         BMO_OP_FLAG_UNTAN_MULTIRES
678 };
679
680 static BMOpDefine bmo_triangulate_def = {
681         "triangulate",
682         {{BMO_OP_SLOT_ELEMENT_BUF, "faces"},
683          {BMO_OP_SLOT_ELEMENT_BUF, "edgeout"},
684          {BMO_OP_SLOT_ELEMENT_BUF, "faceout"},
685          {BMO_OP_SLOT_MAPPING, "facemap"},
686          {BMO_OP_SLOT_BOOL, "use_beauty"},
687          {0} /* null-terminating sentinel */},
688         bmo_triangulate_exec,
689         BMO_OP_FLAG_UNTAN_MULTIRES
690 };
691
692 static BMOpDefine bmo_esubd_def = {
693         "esubd",
694         {{BMO_OP_SLOT_ELEMENT_BUF, "edges"},
695          {BMO_OP_SLOT_INT, "numcuts"},
696          {BMO_OP_SLOT_FLT, "smooth"},
697          {BMO_OP_SLOT_FLT, "fractal"},
698          {BMO_OP_SLOT_INT, "beauty"},
699          {BMO_OP_SLOT_INT, "seed"},
700          {BMO_OP_SLOT_MAPPING, "custompatterns"},
701          {BMO_OP_SLOT_MAPPING, "edgepercents"},
702
703         /* these next three can have multiple types of elements in them */
704          {BMO_OP_SLOT_ELEMENT_BUF, "outinner"},
705          {BMO_OP_SLOT_ELEMENT_BUF, "outsplit"},
706          {BMO_OP_SLOT_ELEMENT_BUF, "geomout"}, /* contains all output geometr */
707
708          {BMO_OP_SLOT_INT,  "quadcornertype"}, //quad corner type, see bmesh_operators.h
709          {BMO_OP_SLOT_BOOL, "gridfill"}, //fill in fully-selected faces with a grid
710          {BMO_OP_SLOT_BOOL, "singleedge"}, //tessellate the case of one edge selected in a quad or triangle
711
712          {0} /* null-terminating sentinel */,
713         },
714         bmo_esubd_exec,
715         BMO_OP_FLAG_UNTAN_MULTIRES
716 };
717
718 static BMOpDefine bmo_del_def = {
719         "del",
720         {{BMO_OP_SLOT_ELEMENT_BUF, "geom"},
721          {BMO_OP_SLOT_INT, "context"},
722          {0} /* null-terminating sentinel */},
723         bmo_del_exec,
724         0
725 };
726
727 static BMOpDefine bmo_dupe_def = {
728         "dupe",
729         {{BMO_OP_SLOT_ELEMENT_BUF, "geom"},
730          {BMO_OP_SLOT_ELEMENT_BUF, "origout"},
731          {BMO_OP_SLOT_ELEMENT_BUF, "newout"},
732         /* facemap maps from source faces to dupe
733          * faces, and from dupe faces to source faces */
734          {BMO_OP_SLOT_MAPPING, "facemap"},
735          {BMO_OP_SLOT_MAPPING, "boundarymap"},
736          {BMO_OP_SLOT_MAPPING, "isovertmap"},
737          {BMO_OP_SLOT_PNT, "dest"}, /* destination bmesh, if NULL will use current on */
738          {0} /* null-terminating sentinel */},
739         bmo_dupe_exec,
740         0
741 };
742
743 static BMOpDefine bmo_split_def = {
744         "split",
745         {{BMO_OP_SLOT_ELEMENT_BUF, "geom"},
746          {BMO_OP_SLOT_ELEMENT_BUF, "geomout"},
747          {BMO_OP_SLOT_MAPPING, "boundarymap"},
748          {BMO_OP_SLOT_MAPPING, "isovertmap"},
749          {BMO_OP_SLOT_PNT, "dest"}, /* destination bmesh, if NULL will use current on */
750          {BMO_OP_SLOT_BOOL, "use_only_faces"}, /* when enabled. don't duplicate loose verts/edges */
751          {0} /* null-terminating sentinel */},
752         bmo_split_exec,
753         0
754 };
755
756 /*
757  * Spin
758  *
759  * Extrude or duplicate geometry a number of times,
760  * rotating and possibly translating after each step
761  */
762 static BMOpDefine bmo_spin_def = {
763         "spin",
764         {{BMO_OP_SLOT_ELEMENT_BUF, "geom"},
765          {BMO_OP_SLOT_ELEMENT_BUF, "lastout"}, /* result of last step */
766          {BMO_OP_SLOT_VEC, "cent"}, /* rotation center */
767          {BMO_OP_SLOT_VEC, "axis"}, /* rotation axis */
768          {BMO_OP_SLOT_VEC, "dvec"}, /* translation delta per step */
769          {BMO_OP_SLOT_FLT, "ang"}, /* total rotation angle (degrees) */
770          {BMO_OP_SLOT_INT, "steps"}, /* number of steps */
771          {BMO_OP_SLOT_BOOL, "do_dupli"}, /* duplicate or extrude? */
772          {0} /* null-terminating sentinel */},
773         bmo_spin_exec,
774         0
775 };
776
777
778 /*
779  * Similar faces search
780  *
781  * Find similar faces (area/material/perimeter, ...).
782  */
783 static BMOpDefine bmo_similarfaces_def = {
784         "similarfaces",
785         {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
786          {BMO_OP_SLOT_ELEMENT_BUF, "faceout"}, /* output faces */
787          {BMO_OP_SLOT_INT, "type"},                     /* type of selection */
788          {BMO_OP_SLOT_FLT, "thresh"},           /* threshold of selection */
789          {0} /* null-terminating sentinel */},
790         bmo_similarfaces_exec,
791         0
792 };
793
794 /*
795  * Similar edges search
796  *
797  *  Find similar edges (length, direction, edge, seam, ...).
798  */
799 static BMOpDefine bmo_similaredges_def = {
800         "similaredges",
801         {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edges */
802          {BMO_OP_SLOT_ELEMENT_BUF, "edgeout"}, /* output edges */
803          {BMO_OP_SLOT_INT, "type"},                     /* type of selection */
804          {BMO_OP_SLOT_FLT, "thresh"},           /* threshold of selection */
805          {0} /* null-terminating sentinel */},
806         bmo_similaredges_exec,
807         0
808 };
809
810 /*
811  * Similar vertices search
812  *
813  * Find similar vertices (normal, face, vertex group, ...).
814  */
815 static BMOpDefine bmo_similarverts_def = {
816         "similarverts",
817         {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */
818          {BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, /* output vertices */
819          {BMO_OP_SLOT_INT, "type"},                     /* type of selection */
820          {BMO_OP_SLOT_FLT, "thresh"},           /* threshold of selection */
821          {0} /* null-terminating sentinel */},
822         bmo_similarverts_exec,
823         0
824 };
825
826 /*
827  * uv rotation
828  * cycle the uvs
829  */
830 static BMOpDefine bmo_face_rotateuvs_def = {
831         "face_rotateuvs",
832         {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
833          {BMO_OP_SLOT_INT, "dir"},                      /* direction */
834          {0} /* null-terminating sentinel */},
835         bmo_face_rotateuvs_exec,
836         0
837 };
838
839 /*
840  * uv reverse
841  * reverse the uvs
842  */
843 static BMOpDefine bmo_face_reverseuvs_def = {
844         "face_reverseuvs",
845         {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
846          {0} /* null-terminating sentinel */},
847         bmo_face_reverseuvs_exec,
848         0
849 };
850
851 /*
852  * color rotation
853  * cycle the colors
854  */
855 static BMOpDefine bmo_face_rotatecolors_def = {
856         "face_rotatecolors",
857         {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
858          {BMO_OP_SLOT_INT, "dir"},                      /* direction */
859          {0} /* null-terminating sentinel */},
860         bmo_rotatecolors_exec,
861         0
862 };
863
864 /*
865  * color reverse
866  * reverse the colors
867  */
868 static BMOpDefine bmo_face_reversecolors_def = {
869         "face_reversecolors",
870         {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
871          {0} /* null-terminating sentinel */},
872         bmo_face_reversecolors_exec,
873         0
874 };
875
876 /*
877  * Similar vertices search
878  *
879  * Find similar vertices (normal, face, vertex group, ...).
880  */
881 static BMOpDefine bmo_vertexshortestpath_def = {
882         "vertexshortestpath",
883         {{BMO_OP_SLOT_ELEMENT_BUF, "startv"}, /* start vertex */
884          {BMO_OP_SLOT_ELEMENT_BUF, "endv"}, /* end vertex */
885          {BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, /* output vertices */
886          {BMO_OP_SLOT_INT, "type"},                     /* type of selection */
887          {0} /* null-terminating sentinel */},
888         bmo_vertexshortestpath_exec,
889         0
890 };
891
892 /*
893  * Edge Split
894  *
895  * Disconnects faces along input edges.
896  */
897 static BMOpDefine bmo_edgesplit_def = {
898         "edgesplit",
899         {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edges */
900          {BMO_OP_SLOT_ELEMENT_BUF, "edgeout"}, /* old output disconnected edges */
901          /* needed for vertex rip so we can rip only half an edge at a boundary wich would otherwise split off */
902          {BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* optional tag verts, use to have greater control of splits */
903          {BMO_OP_SLOT_BOOL,        "use_verts"}, /* use 'verts' for splitting, else just find verts to split from edges */
904          {0} /* null-terminating sentinel */},
905         bmo_edgesplit_exec,
906         BMO_OP_FLAG_UNTAN_MULTIRES
907 };
908
909 /*
910  * Create Grid
911  *
912  * Creates a grid with a variable number of subdivisions
913  */
914 static BMOpDefine bmo_create_grid_def = {
915         "create_grid",
916         {{BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, //output verts
917          {BMO_OP_SLOT_INT,         "xsegments"}, //number of x segments
918          {BMO_OP_SLOT_INT,         "ysegments"}, //number of y segments
919          {BMO_OP_SLOT_FLT,         "size"}, //size of the grid
920          {BMO_OP_SLOT_MAT,         "mat"}, //matrix to multiply the new geometry with
921          {0, /* null-terminating sentinel */}},
922         bmo_create_grid_exec,
923         0,
924 };
925
926 /*
927  * Create UV Sphere
928  *
929  * Creates a grid with a variable number of subdivisions
930  */
931 static BMOpDefine bmo_create_uvsphere_def = {
932         "create_uvsphere",
933         {{BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, //output verts
934          {BMO_OP_SLOT_INT,         "segments"}, //number of u segments
935          {BMO_OP_SLOT_INT,         "revolutions"}, //number of v segment
936          {BMO_OP_SLOT_FLT,         "diameter"}, //diameter
937          {BMO_OP_SLOT_MAT,         "mat"}, //matrix to multiply the new geometry with--
938          {0, /* null-terminating sentinel */}},
939         bmo_create_uvsphere_exec,
940         0,
941 };
942
943 /*
944  * Create Ico Sphere
945  *
946  * Creates a grid with a variable number of subdivisions
947  */
948 static BMOpDefine bmo_create_icosphere_def = {
949         "create_icosphere",
950         {{BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, //output verts
951          {BMO_OP_SLOT_INT,         "subdivisions"}, //how many times to recursively subdivide the sphere
952          {BMO_OP_SLOT_FLT,         "diameter"}, //diameter
953          {BMO_OP_SLOT_MAT,         "mat"}, //matrix to multiply the new geometry with
954          {0, /* null-terminating sentinel */}},
955         bmo_create_icosphere_exec,
956         0,
957 };
958
959 /*
960  * Create Suzanne
961  *
962  * Creates a monkey.  Be wary.
963  */
964 static BMOpDefine bmo_create_monkey_def = {
965         "create_monkey",
966         {{BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, //output verts
967          {BMO_OP_SLOT_MAT, "mat"}, //matrix to multiply the new geometry with--
968          {0, /* null-terminating sentinel */}},
969         bmo_create_monkey_exec,
970         0,
971 };
972
973 /*
974  * Create Cone
975  *
976  * Creates a cone with variable depth at both ends
977  */
978 static BMOpDefine bmo_create_cone_def = {
979         "create_cone",
980         {{BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, //output verts
981          {BMO_OP_SLOT_BOOL, "cap_ends"}, //wheter or not to fill in the ends with faces
982          {BMO_OP_SLOT_BOOL, "cap_tris"}, //fill ends with triangles instead of ngons
983          {BMO_OP_SLOT_INT, "segments"},
984          {BMO_OP_SLOT_FLT, "diameter1"}, //diameter of one end
985          {BMO_OP_SLOT_FLT, "diameter2"}, //diameter of the opposite
986          {BMO_OP_SLOT_FLT, "depth"}, //distance between ends
987          {BMO_OP_SLOT_MAT, "mat"}, //matrix to multiply the new geometry with--
988          {0, /* null-terminating sentinel */}},
989         bmo_create_cone_exec,
990         0,
991 };
992
993 /*
994  * Creates a circle
995  */
996 static BMOpDefine bmo_create_circle_def = {
997         "create_circle",
998         {{BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, //output verts
999          {BMO_OP_SLOT_BOOL, "cap_ends"}, //wheter or not to fill in the ends with faces
1000          {BMO_OP_SLOT_BOOL, "cap_tris"}, //fill ends with triangles instead of ngons
1001          {BMO_OP_SLOT_INT, "segments"},
1002          {BMO_OP_SLOT_FLT, "diameter"}, //diameter of one end
1003          {BMO_OP_SLOT_MAT, "mat"}, //matrix to multiply the new geometry with--
1004          {0, /* null-terminating sentinel */}},
1005         bmo_create_circle_exec,
1006         0,
1007 };
1008
1009 /*
1010  * Create Cone
1011  *
1012  * Creates a cone with variable depth at both ends
1013  */
1014 static BMOpDefine bmo_create_cube_def = {
1015         "create_cube",
1016         {{BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, //output verts
1017          {BMO_OP_SLOT_FLT, "size"}, //size of the cube
1018          {BMO_OP_SLOT_MAT, "mat"}, //matrix to multiply the new geometry with--
1019          {0, /* null-terminating sentinel */}},
1020         bmo_create_cube_exec,
1021         0,
1022 };
1023
1024 /*
1025  * Bevel
1026  *
1027  * Bevels edges and vertices
1028  */
1029 static BMOpDefine bmo_bevel_def = {
1030         "bevel",
1031         {{BMO_OP_SLOT_ELEMENT_BUF, "geom"}, /* input edges and vertices */
1032          {BMO_OP_SLOT_ELEMENT_BUF, "face_spans"}, /* new geometry */
1033          {BMO_OP_SLOT_ELEMENT_BUF, "face_holes"}, /* new geometry */
1034          {BMO_OP_SLOT_BOOL, "use_lengths"}, /* grab edge lengths from a PROP_FLT customdata laye */
1035          {BMO_OP_SLOT_BOOL, "use_even"}, /* corner vert placement: use shell/angle calculations  */
1036          {BMO_OP_SLOT_BOOL, "use_dist"}, /* corner vert placement: evaluate percent as a distance,
1037                                           * modifier uses this. We could do this as another float setting */
1038          {BMO_OP_SLOT_INT, "lengthlayer"}, /* which PROP_FLT layer to us */
1039          {BMO_OP_SLOT_FLT, "percent"}, /* percentage to expand bevelled edge */
1040          {0} /* null-terminating sentinel */},
1041         bmo_bevel_exec,
1042         BMO_OP_FLAG_UNTAN_MULTIRES
1043 };
1044
1045 /*
1046  * Beautify Fill
1047  *
1048  * Makes triangle a bit nicer
1049  */
1050 static BMOpDefine bmo_beautify_fill_def = {
1051         "beautify_fill",
1052         {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
1053          {BMO_OP_SLOT_ELEMENT_BUF, "constrain_edges"}, /* edges that can't be flipped */
1054          {BMO_OP_SLOT_ELEMENT_BUF, "geomout"}, /* new flipped faces and edges */
1055          {0} /* null-terminating sentinel */},
1056         bmo_beautify_fill_exec,
1057         BMO_OP_FLAG_UNTAN_MULTIRES
1058 };
1059
1060 /*
1061  * Triangle Fill
1062  *
1063  * Fill edges with triangles
1064  */
1065 static BMOpDefine bmo_triangle_fill_def = {
1066         "triangle_fill",
1067         {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edges */
1068          {BMO_OP_SLOT_ELEMENT_BUF, "geomout"}, /* new faces and edges */
1069          {0} /* null-terminating sentinel */},
1070         bmo_triangle_fill_exec,
1071         BMO_OP_FLAG_UNTAN_MULTIRES
1072 };
1073
1074 /*
1075  * Solidify
1076  *
1077  * Turns a mesh into a shell with thickness
1078  */
1079 static BMOpDefine bmo_solidify_def = {
1080         "solidify",
1081         {{BMO_OP_SLOT_ELEMENT_BUF, "geom"},
1082          {BMO_OP_SLOT_FLT, "thickness"},
1083          {BMO_OP_SLOT_ELEMENT_BUF, "geomout"},
1084          {0}},
1085         bmo_solidify_face_region_exec,
1086         0
1087 };
1088
1089 /*
1090  * Face Inset
1091  *
1092  * Extrudes faces individually.
1093  */
1094 static BMOpDefine bmo_inset_def = {
1095         "inset",
1096         {{BMO_OP_SLOT_ELEMENT_BUF, "faces"},   /* input faces */
1097          {BMO_OP_SLOT_ELEMENT_BUF, "faceout"}, /* output faces */
1098          {BMO_OP_SLOT_BOOL, "use_boundary"},
1099          {BMO_OP_SLOT_BOOL, "use_even_offset"},
1100          {BMO_OP_SLOT_BOOL, "use_relative_offset"},
1101          {BMO_OP_SLOT_FLT, "thickness"},
1102          {BMO_OP_SLOT_FLT, "depth"},
1103          {BMO_OP_SLOT_BOOL, "use_outset"},
1104          {0} /* null-terminating sentinel */},
1105         bmo_inset_exec,
1106         0
1107 };
1108
1109 /*
1110  * Vertex Slide
1111  *
1112  * Translates vertes along an edge
1113  */
1114 static BMOpDefine bmo_vertex_slide_def = {
1115         "vertex_slide",
1116         {{BMO_OP_SLOT_ELEMENT_BUF, "vert"},
1117          {BMO_OP_SLOT_ELEMENT_BUF, "edge"},
1118          {BMO_OP_SLOT_ELEMENT_BUF, "vertout"},
1119          {BMO_OP_SLOT_FLT, "distance_t"},
1120          {0} /* null-terminating sentinel */},
1121         bmo_vertex_slide_exec,
1122         BMO_OP_FLAG_UNTAN_MULTIRES
1123 };
1124
1125
1126 BMOpDefine *opdefines[] = {
1127         &bmo_split_def,
1128         &bmo_spin_def,
1129         &bmo_dupe_def,
1130         &bmo_del_def,
1131         &bmo_esubd_def,
1132         &bmo_triangulate_def,
1133         &bmo_dissolve_faces_def,
1134         &bmo_dissolve_edges_def,
1135         &bmo_dissolve_edge_loop_def,
1136         &bmo_dissolve_verts_def,
1137         &bmo_dissolve_limit_def,
1138         &bmo_extrude_face_region_def,
1139         &bmo_connectverts_def,
1140         &bmo_extrude_vert_indiv_def,
1141         &bmo_mesh_to_bmesh_def,
1142         &bmo_object_load_bmesh_def,
1143         &bmo_transform_def,
1144         &bmo_translate_def,
1145         &bmo_rotate_def,
1146         &bmo_edgenet_fill_def,
1147         &bmo_contextual_create_def,
1148         &bmo_makevert_def,
1149         &bmo_weldverts_def,
1150         &bmo_removedoubles_def,
1151         &bmo_finddoubles_def,
1152         &bmo_mirror_def,
1153         &bmo_edgebisect_def,
1154         &bmo_reversefaces_def,
1155         &bmo_edgerotate_def,
1156         &bmo_regionextend_def,
1157         &bmo_righthandfaces_def,
1158         &bmo_vertexsmooth_def,
1159         &bmo_extrude_edge_only_def,
1160         &bmo_extrude_indivface_def,
1161         &bmo_collapse_uvs_def,
1162         &bmo_pointmerge_def,
1163         &bmo_collapse_def,
1164         &bmo_similarfaces_def,
1165         &bmo_similaredges_def,
1166         &bmo_similarverts_def,
1167         &bmo_pointmerge_facedata_def,
1168         &bmo_vert_average_facedata_def,
1169         &bmo_face_rotateuvs_def,
1170         &bmo_bmesh_to_mesh_def,
1171         &bmo_face_reverseuvs_def,
1172         &bmo_edgenet_prepare_def,
1173         &bmo_face_rotatecolors_def,
1174         &bmo_face_reversecolors_def,
1175         &bmo_vertexshortestpath_def,
1176         &bmo_scale_def,
1177         &bmo_edgesplit_def,
1178         &bmo_automerge_def,
1179         &bmo_create_uvsphere_def,
1180         &bmo_create_grid_def,
1181         &bmo_create_icosphere_def,
1182         &bmo_create_monkey_def,
1183         &bmo_create_cube_def,
1184         &bmo_create_circle_def,
1185         &bmo_create_cone_def,
1186         &bmo_join_triangles_def,
1187         &bmo_bevel_def,
1188         &bmo_beautify_fill_def,
1189         &bmo_triangle_fill_def,
1190         &bmo_bridge_loops_def,
1191         &bmo_solidify_def,
1192         &bmo_inset_def,
1193         &bmo_vertex_slide_def,
1194 };
1195
1196 int bmesh_total_ops = (sizeof(opdefines) / sizeof(void *));