Partially replace convex hull implementation with Bullet implementation
[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         /* note, this is for stand-alone edges only, not edges which are apart of newly created faces */
412          {BMO_OP_SLOT_ELEMENT_BUF, "edgeout"},     /* newly-made edge(s) */
413          {BMO_OP_SLOT_INT,         "mat_nr"},      /* material to use */
414          {BMO_OP_SLOT_BOOL,        "use_smooth"},  /* material to use */
415          {0, /* null-terminating sentinel */}},
416         bmo_contextual_create_exec,
417         BMO_OP_FLAG_UNTAN_MULTIRES,
418 };
419
420 /*
421  * Bridge edge loops with faces
422  */
423 static BMOpDefine bmo_bridge_loops_def = {
424         "bridge_loops",
425         {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edge */
426          {BMO_OP_SLOT_ELEMENT_BUF, "faceout"}, /* new face */
427          {BMO_OP_SLOT_BOOL,        "use_merge"},
428          {BMO_OP_SLOT_FLT,         "merge_factor"},
429          {0, /* null-terminating sentinel */}},
430         bmo_bridge_loops_exec,
431         0,
432 };
433
434 static BMOpDefine bmo_edgenet_fill_def = {
435         "edgenet_fill",
436         {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edge */
437          {BMO_OP_SLOT_MAPPING,     "restrict"}, /* restricts edges to groups.  maps edges to integer */
438          {BMO_OP_SLOT_BOOL,        "use_restrict"},
439          {BMO_OP_SLOT_BOOL,        "use_fill_check"},
440          {BMO_OP_SLOT_ELEMENT_BUF, "excludefaces"}, /* list of faces to ignore for manifold check */
441          {BMO_OP_SLOT_MAPPING,     "faceout_groupmap"}, /* maps new faces to the group numbers they came fro */
442          {BMO_OP_SLOT_ELEMENT_BUF, "faceout"},     /* new face */
443          {BMO_OP_SLOT_INT,         "mat_nr"},      /* material to use */
444          {BMO_OP_SLOT_BOOL,        "use_smooth"},  /* material to use */
445          {0, /* null-terminating sentinel */}},
446         bmo_edgenet_fill_exec,
447         0,
448 };
449
450 /*
451  * Edgenet Prepare
452  *
453  * Identifies several useful edge loop cases and modifies them so
454  * they'll become a face when edgenet_fill is called.  The cases covered are:
455  *
456  * - One single loop; an edge is added to connect the ends
457  * - Two loops; two edges are added to connect the endpoints (based on the
458  *   shortest distance between each endpont).
459  */
460 static BMOpDefine bmo_edgenet_prepare_def = {
461         "edgenet_prepare",
462         {{BMO_OP_SLOT_ELEMENT_BUF, "edges"},    /* input edges */
463          {BMO_OP_SLOT_ELEMENT_BUF, "edgeout"},  /* new edges */
464          {0, /* null-terminating sentinel */}},
465         bmo_edgenet_prepare,
466         0,
467 };
468
469 /*
470  * Rotate
471  *
472  * Rotate vertices around a center, using a 3x3 rotation
473  * matrix.  Equivalent of the old rotateflag function.
474  */
475 static BMOpDefine bmo_rotate_def = {
476         "rotate",
477         {{BMO_OP_SLOT_VEC, "cent"},  /* center of rotation */
478          {BMO_OP_SLOT_MAT, "mat"},   /* matrix defining rotation */
479          {BMO_OP_SLOT_ELEMENT_BUF, "verts"},  /* input vertices */
480          {0, /* null-terminating sentinel */}},
481         bmo_rotate_exec,
482         0,
483 };
484
485 /*
486  * Translate
487  *
488  * Translate vertices by an offset.  Equivalent of the
489  * old translateflag function.
490  */
491 static BMOpDefine bmo_translate_def = {
492         "translate",
493         {{BMO_OP_SLOT_VEC, "vec"},  /* translation offset */
494          {BMO_OP_SLOT_ELEMENT_BUF, "verts"},  /* input vertices */
495          {0, /* null-terminating sentinel */}},
496         bmo_translate_exec,
497         0,
498 };
499
500 /*
501  * Scale
502  *
503  * Scales vertices by an offset.
504  */
505 static BMOpDefine bmo_scale_def = {
506         "scale",
507         {{BMO_OP_SLOT_VEC, "vec"},  /* scale factor */
508          {BMO_OP_SLOT_ELEMENT_BUF, "verts"},  /* input vertices */
509          {0, /* null-terminating sentinel */}},
510         bmo_scale_exec,
511         0,
512 };
513
514
515 /*
516  * Transform
517  *
518  * Transforms a set of vertices by a matrix.  Multiplies
519  * the vertex coordinates with the matrix.
520  */
521 static BMOpDefine bmo_transform_def = {
522         "transform",
523         {{BMO_OP_SLOT_MAT, "mat"},  /* transform matrix */
524          {BMO_OP_SLOT_ELEMENT_BUF, "verts"},  /* input vertices */
525          {0, /* null-terminating sentinel */}},
526         bmo_transform_exec,
527         0,
528 };
529
530 /*
531  * Object Load BMesh
532  *
533  * Loads a bmesh into an object/mesh.  This is a "private"
534  * bmop.
535  */
536 static BMOpDefine bmo_object_load_bmesh_def = {
537         "object_load_bmesh",
538         {{BMO_OP_SLOT_PTR, "scene"},
539          {BMO_OP_SLOT_PTR, "object"},
540          {0, /* null-terminating sentinel */}},
541         bmo_object_load_bmesh_exec,
542         0,
543 };
544
545
546 /*
547  * BMesh to Mesh
548  *
549  * Converts a bmesh to a Mesh.  This is reserved for exiting editmode.
550  */
551 static BMOpDefine bmo_bmesh_to_mesh_def = {
552         "bmesh_to_mesh",
553         {{BMO_OP_SLOT_PTR, "mesh"},    /* pointer to a mesh structure to fill in */
554          {BMO_OP_SLOT_PTR, "object"},  /* pointer to an object structure */
555          {BMO_OP_SLOT_BOOL, "notessellation"},  /* don't calculate mfaces */
556          {0, /* null-terminating sentinel */}},
557         bmo_bmesh_to_mesh_exec,
558         0,
559 };
560
561 /*
562  * Mesh to BMesh
563  *
564  * Load the contents of a mesh into the bmesh.  this bmop is private, it's
565  * reserved exclusively for entering editmode.
566  */
567 static BMOpDefine bmo_mesh_to_bmesh_def = {
568         "mesh_to_bmesh",
569         {{BMO_OP_SLOT_PTR, "mesh"},    /* pointer to a Mesh structure */
570          {BMO_OP_SLOT_PTR, "object"},  /* pointer to an Object structure */
571          {BMO_OP_SLOT_BOOL, "set_shapekey"},  /* load active shapekey coordinates into verts */
572          {0, /* null-terminating sentinel */}},
573         bmo_mesh_to_bmesh_exec,
574         0
575 };
576
577 /*
578  * Individual Face Extrude
579  *
580  * Extrudes faces individually.
581  */
582 static BMOpDefine bmo_extrude_discrete_faces_def = {
583         "extrude_discrete_faces",
584         {{BMO_OP_SLOT_ELEMENT_BUF, "faces"},     /* input faces */
585          {BMO_OP_SLOT_ELEMENT_BUF, "faceout"},   /* output faces */
586          {BMO_OP_SLOT_ELEMENT_BUF, "skirtout"},  /* output skirt geometry, faces and edges */
587          {0} /* null-terminating sentinel */},
588         bmo_extrude_discrete_faces_exec,
589         0
590 };
591
592 /*
593  * Extrude Only Edges
594  *
595  * Extrudes Edges into faces, note that this is very simple, there's no fancy
596  * winged extrusion.
597  */
598 static BMOpDefine bmo_extrude_edge_only_def = {
599         "extrude_edge_only",
600         {{BMO_OP_SLOT_ELEMENT_BUF, "edges"},    /* input vertices */
601          {BMO_OP_SLOT_ELEMENT_BUF, "geomout"},  /* output geometry */
602          {0} /* null-terminating sentinel */},
603         bmo_extrude_edge_only_exec,
604         0
605 };
606
607 /*
608  * Individual Vertex Extrude
609  *
610  * Extrudes wire edges from vertices.
611  */
612 static BMOpDefine bmo_extrude_vert_indiv_def = {
613         "extrude_vert_indiv",
614         {{BMO_OP_SLOT_ELEMENT_BUF, "verts"},    /* input vertices */
615          {BMO_OP_SLOT_ELEMENT_BUF, "edgeout"},  /* output wire edges */
616          {BMO_OP_SLOT_ELEMENT_BUF, "vertout"},  /* output vertices */
617          {0} /* null-terminating sentinel */},
618         bmo_extrude_vert_indiv_exec,
619         0
620 };
621
622 static BMOpDefine bmo_connect_verts_def = {
623         "connect_verts",
624         {{BMO_OP_SLOT_ELEMENT_BUF, "verts"},
625          {BMO_OP_SLOT_ELEMENT_BUF, "edgeout"},
626          {0} /* null-terminating sentinel */},
627         bmo_connect_verts_exec,
628         BMO_OP_FLAG_UNTAN_MULTIRES
629 };
630
631 static BMOpDefine bmo_extrude_face_region_def = {
632         "extrude_face_region",
633         {{BMO_OP_SLOT_ELEMENT_BUF, "edgefacein"},
634          {BMO_OP_SLOT_MAPPING, "exclude"},
635          {BMO_OP_SLOT_BOOL, "alwayskeeporig"},
636          {BMO_OP_SLOT_ELEMENT_BUF, "geomout"},
637          {0} /* null-terminating sentinel */},
638         bmo_extrude_face_region_exec,
639         0
640 };
641
642 static BMOpDefine bmo_dissolve_verts_def = {
643         "dissolve_verts",
644         {{BMO_OP_SLOT_ELEMENT_BUF, "verts"},
645          {0} /* null-terminating sentinel */},
646         bmo_dissolve_verts_exec,
647         BMO_OP_FLAG_UNTAN_MULTIRES
648 };
649
650 static BMOpDefine bmo_dissolve_edges_def = {
651         "dissolve_edges",
652         {{BMO_OP_SLOT_ELEMENT_BUF, "edges"},
653          {BMO_OP_SLOT_ELEMENT_BUF, "regionout"},
654          {BMO_OP_SLOT_BOOL, "use_verts"},  /* dissolve verts left between only 2 edges. */
655          {0} /* null-terminating sentinel */},
656         bmo_dissolve_edges_exec,
657         BMO_OP_FLAG_UNTAN_MULTIRES
658 };
659
660 static BMOpDefine bmo_dissolve_edge_loop_def = {
661         "dissolve_edge_loop",
662         {{BMO_OP_SLOT_ELEMENT_BUF, "edges"},
663          {BMO_OP_SLOT_ELEMENT_BUF, "regionout"},
664          {0} /* null-terminating sentinel */},
665         bmo_dissolve_edgeloop_exec,
666         BMO_OP_FLAG_UNTAN_MULTIRES
667 };
668
669 static BMOpDefine bmo_dissolve_faces_def = {
670         "dissolve_faces",
671         {{BMO_OP_SLOT_ELEMENT_BUF, "faces"},
672          {BMO_OP_SLOT_ELEMENT_BUF, "regionout"},
673          {BMO_OP_SLOT_BOOL, "use_verts"},  /* dissolve verts left between only 2 edges. */
674          {0} /* null-terminating sentinel */},
675         bmo_dissolve_faces_exec,
676         BMO_OP_FLAG_UNTAN_MULTIRES
677 };
678
679 static BMOpDefine bmo_dissolve_limit_def = {
680         "dissolve_limit",
681         {{BMO_OP_SLOT_FLT, "angle_limit"}, /* total rotation angle (degrees) */
682          {BMO_OP_SLOT_BOOL, "use_dissolve_boundaries"},
683          {BMO_OP_SLOT_ELEMENT_BUF, "verts"},
684          {BMO_OP_SLOT_ELEMENT_BUF, "edges"},
685          {0} /* null-terminating sentinel */},
686         bmo_dissolve_limit_exec,
687         BMO_OP_FLAG_UNTAN_MULTIRES
688 };
689
690 static BMOpDefine bmo_triangulate_def = {
691         "triangulate",
692         {{BMO_OP_SLOT_ELEMENT_BUF, "faces"},
693          {BMO_OP_SLOT_ELEMENT_BUF, "edgeout"},
694          {BMO_OP_SLOT_ELEMENT_BUF, "faceout"},
695          {BMO_OP_SLOT_MAPPING, "facemap"},
696          {BMO_OP_SLOT_BOOL, "use_beauty"},
697          {0} /* null-terminating sentinel */},
698         bmo_triangulate_exec,
699         BMO_OP_FLAG_UNTAN_MULTIRES
700 };
701
702 static BMOpDefine bmo_unsubdivide_def = {
703         "unsubdivide",
704         {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */
705          {BMO_OP_SLOT_INT, "iterations"},
706          {0} /* null-terminating sentinel */},
707         bmo_unsubdivide_exec,
708         BMO_OP_FLAG_UNTAN_MULTIRES
709 };
710
711 static BMOpDefine bmo_subdivide_edges_def = {
712         "subdivide_edges",
713         {{BMO_OP_SLOT_ELEMENT_BUF, "edges"},
714          {BMO_OP_SLOT_FLT, "smooth"},
715          {BMO_OP_SLOT_FLT, "fractal"},
716          {BMO_OP_SLOT_FLT, "along_normal"},
717          {BMO_OP_SLOT_INT, "numcuts"},
718          {BMO_OP_SLOT_INT, "seed"},
719          {BMO_OP_SLOT_MAPPING, "custompatterns"},
720          {BMO_OP_SLOT_MAPPING, "edgepercents"},
721
722         /* these next three can have multiple types of elements in them */
723          {BMO_OP_SLOT_ELEMENT_BUF, "outinner"},
724          {BMO_OP_SLOT_ELEMENT_BUF, "outsplit"},
725          {BMO_OP_SLOT_ELEMENT_BUF, "geomout"}, /* contains all output geometr */
726
727          {BMO_OP_SLOT_INT,  "quadcornertype"}, /* quad corner type, see bmesh_operators.h */
728          {BMO_OP_SLOT_BOOL, "use_gridfill"},   /* fill in fully-selected faces with a grid */
729          {BMO_OP_SLOT_BOOL, "use_singleedge"}, /* tessellate the case of one edge selected in a quad or triangle */
730          {BMO_OP_SLOT_BOOL, "use_sphere"},     /* for making new primitives only */
731
732          {0} /* null-terminating sentinel */,
733         },
734         bmo_subdivide_edges_exec,
735         BMO_OP_FLAG_UNTAN_MULTIRES
736 };
737
738 static BMOpDefine bmo_delete_def = {
739         "delete",
740         {{BMO_OP_SLOT_ELEMENT_BUF, "geom"},
741          {BMO_OP_SLOT_INT, "context"},
742          {0} /* null-terminating sentinel */},
743         bmo_delete_exec,
744         0
745 };
746
747 static BMOpDefine bmo_duplicate_def = {
748         "duplicate",
749         {{BMO_OP_SLOT_ELEMENT_BUF, "geom"},
750          {BMO_OP_SLOT_ELEMENT_BUF, "origout"},
751          {BMO_OP_SLOT_ELEMENT_BUF, "newout"},
752         /* facemap maps from source faces to dupe
753          * faces, and from dupe faces to source faces */
754          {BMO_OP_SLOT_MAPPING, "facemap"},
755          {BMO_OP_SLOT_MAPPING, "boundarymap"},
756          {BMO_OP_SLOT_MAPPING, "isovertmap"},
757          {BMO_OP_SLOT_PTR, "dest"}, /* destination bmesh, if NULL will use current on */
758          {0} /* null-terminating sentinel */},
759         bmo_duplicate_exec,
760         0
761 };
762
763 static BMOpDefine bmo_split_def = {
764         "split",
765         {{BMO_OP_SLOT_ELEMENT_BUF, "geom"},
766          {BMO_OP_SLOT_ELEMENT_BUF, "geomout"},
767          {BMO_OP_SLOT_MAPPING, "boundarymap"},
768          {BMO_OP_SLOT_MAPPING, "isovertmap"},
769          {BMO_OP_SLOT_PTR, "dest"}, /* destination bmesh, if NULL will use current on */
770          {BMO_OP_SLOT_BOOL, "use_only_faces"}, /* when enabled. don't duplicate loose verts/edges */
771          {0} /* null-terminating sentinel */},
772         bmo_split_exec,
773         0
774 };
775
776 /*
777  * Spin
778  *
779  * Extrude or duplicate geometry a number of times,
780  * rotating and possibly translating after each step
781  */
782 static BMOpDefine bmo_spin_def = {
783         "spin",
784         {{BMO_OP_SLOT_ELEMENT_BUF, "geom"},
785          {BMO_OP_SLOT_ELEMENT_BUF, "lastout"}, /* result of last step */
786          {BMO_OP_SLOT_VEC, "cent"}, /* rotation center */
787          {BMO_OP_SLOT_VEC, "axis"}, /* rotation axis */
788          {BMO_OP_SLOT_VEC, "dvec"}, /* translation delta per step */
789          {BMO_OP_SLOT_FLT, "ang"}, /* total rotation angle (degrees) */
790          {BMO_OP_SLOT_INT, "steps"}, /* number of steps */
791          {BMO_OP_SLOT_BOOL, "do_dupli"}, /* duplicate or extrude? */
792          {0} /* null-terminating sentinel */},
793         bmo_spin_exec,
794         0
795 };
796
797
798 /*
799  * Similar faces search
800  *
801  * Find similar faces (area/material/perimeter, ...).
802  */
803 static BMOpDefine bmo_similar_faces_def = {
804         "similar_faces",
805         {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
806          {BMO_OP_SLOT_ELEMENT_BUF, "faceout"}, /* output faces */
807          {BMO_OP_SLOT_INT, "type"},                     /* type of selection */
808          {BMO_OP_SLOT_FLT, "thresh"},           /* threshold of selection */
809          {0} /* null-terminating sentinel */},
810         bmo_similar_faces_exec,
811         0
812 };
813
814 /*
815  * Similar edges search
816  *
817  *  Find similar edges (length, direction, edge, seam, ...).
818  */
819 static BMOpDefine bmo_similar_edges_def = {
820         "similar_edges",
821         {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edges */
822          {BMO_OP_SLOT_ELEMENT_BUF, "edgeout"}, /* output edges */
823          {BMO_OP_SLOT_INT, "type"},                     /* type of selection */
824          {BMO_OP_SLOT_FLT, "thresh"},           /* threshold of selection */
825          {0} /* null-terminating sentinel */},
826         bmo_similar_edges_exec,
827         0
828 };
829
830 /*
831  * Similar vertices search
832  *
833  * Find similar vertices (normal, face, vertex group, ...).
834  */
835 static BMOpDefine bmo_similar_verts_def = {
836         "similar_verts",
837         {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */
838          {BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, /* output vertices */
839          {BMO_OP_SLOT_INT, "type"},                     /* type of selection */
840          {BMO_OP_SLOT_FLT, "thresh"},           /* threshold of selection */
841          {0} /* null-terminating sentinel */},
842         bmo_similar_verts_exec,
843         0
844 };
845
846 /*
847  * uv rotation
848  * cycle the uvs
849  */
850 static BMOpDefine bmo_rotate_uvs_def = {
851         "rotate_uvs",
852         {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
853          {BMO_OP_SLOT_INT, "dir"},                      /* direction */
854          {0} /* null-terminating sentinel */},
855         bmo_rotate_uvs_exec,
856         0
857 };
858
859 /*
860  * uv reverse
861  * reverse the uvs
862  */
863 static BMOpDefine bmo_reverse_uvs_def = {
864         "reverse_uvs",
865         {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
866          {0} /* null-terminating sentinel */},
867         bmo_reverse_uvs_exec,
868         0
869 };
870
871 /*
872  * color rotation
873  * cycle the colors
874  */
875 static BMOpDefine bmo_rotate_colors_def = {
876         "rotate_colors",
877         {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
878          {BMO_OP_SLOT_INT, "dir"},                      /* direction */
879          {0} /* null-terminating sentinel */},
880         bmo_rotate_colors_exec,
881         0
882 };
883
884 /*
885  * color reverse
886  * reverse the colors
887  */
888 static BMOpDefine bmo_reverse_colors_def = {
889         "reverse_colors",
890         {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
891          {0} /* null-terminating sentinel */},
892         bmo_reverse_colors_exec,
893         0
894 };
895
896 /*
897  * Similar vertices search
898  *
899  * Find similar vertices (normal, face, vertex group, ...).
900  */
901 static BMOpDefine bmo_shortest_path_def = {
902         "shortest_path",
903         {{BMO_OP_SLOT_ELEMENT_BUF, "startv"}, /* start vertex */
904          {BMO_OP_SLOT_ELEMENT_BUF, "endv"}, /* end vertex */
905          {BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, /* output vertices */
906          {BMO_OP_SLOT_INT, "type"},                     /* type of selection */
907          {0} /* null-terminating sentinel */},
908         bmo_shortest_path_exec,
909         0
910 };
911
912 /*
913  * Edge Split
914  *
915  * Disconnects faces along input edges.
916  */
917 static BMOpDefine bmo_split_edges_def = {
918         "split_edges",
919         {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edges */
920          {BMO_OP_SLOT_ELEMENT_BUF, "edgeout"}, /* old output disconnected edges */
921          /* needed for vertex rip so we can rip only half an edge at a boundary wich would otherwise split off */
922          {BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* optional tag verts, use to have greater control of splits */
923          {BMO_OP_SLOT_BOOL,        "use_verts"}, /* use 'verts' for splitting, else just find verts to split from edges */
924          {0} /* null-terminating sentinel */},
925         bmo_split_edges_exec,
926         BMO_OP_FLAG_UNTAN_MULTIRES
927 };
928
929 /*
930  * Create Grid
931  *
932  * Creates a grid with a variable number of subdivisions
933  */
934 static BMOpDefine bmo_create_grid_def = {
935         "create_grid",
936         {{BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, /* output verts */
937          {BMO_OP_SLOT_INT,         "xsegments"}, /* number of x segments */
938          {BMO_OP_SLOT_INT,         "ysegments"}, /* number of y segments */
939          {BMO_OP_SLOT_FLT,         "size"}, /* size of the grid */
940          {BMO_OP_SLOT_MAT,         "mat"}, /* matrix to multiply the new geometry with */
941          {0, /* null-terminating sentinel */}},
942         bmo_create_grid_exec,
943         0,
944 };
945
946 /*
947  * Create UV Sphere
948  *
949  * Creates a grid with a variable number of subdivisions
950  */
951 static BMOpDefine bmo_create_uvsphere_def = {
952         "create_uvsphere",
953         {{BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, /* output verts */
954          {BMO_OP_SLOT_INT,         "segments"}, /* number of u segments */
955          {BMO_OP_SLOT_INT,         "revolutions"}, /* number of v segment */
956          {BMO_OP_SLOT_FLT,         "diameter"}, /* diameter */
957          {BMO_OP_SLOT_MAT,         "mat"}, /* matrix to multiply the new geometry with-- */
958          {0, /* null-terminating sentinel */}},
959         bmo_create_uvsphere_exec,
960         0,
961 };
962
963 /*
964  * Create Ico Sphere
965  *
966  * Creates a grid with a variable number of subdivisions
967  */
968 static BMOpDefine bmo_create_icosphere_def = {
969         "create_icosphere",
970         {{BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, /* output verts */
971          {BMO_OP_SLOT_INT,         "subdivisions"}, /* how many times to recursively subdivide the sphere */
972          {BMO_OP_SLOT_FLT,         "diameter"}, /* diameter */
973          {BMO_OP_SLOT_MAT,         "mat"}, /* matrix to multiply the new geometry with */
974          {0, /* null-terminating sentinel */}},
975         bmo_create_icosphere_exec,
976         0,
977 };
978
979 /*
980  * Create Suzanne
981  *
982  * Creates a monkey.  Be wary.
983  */
984 static BMOpDefine bmo_create_monkey_def = {
985         "create_monkey",
986         {{BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, /* output verts */
987          {BMO_OP_SLOT_MAT, "mat"}, /* matrix to multiply the new geometry with-- */
988          {0, /* null-terminating sentinel */}},
989         bmo_create_monkey_exec,
990         0,
991 };
992
993 /*
994  * Create Cone
995  *
996  * Creates a cone with variable depth at both ends
997  */
998 static BMOpDefine bmo_create_cone_def = {
999         "create_cone",
1000         {{BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, /* output verts */
1001          {BMO_OP_SLOT_BOOL, "cap_ends"}, /* wheter or not to fill in the ends with faces */
1002          {BMO_OP_SLOT_BOOL, "cap_tris"}, /* fill ends with triangles instead of ngons */
1003          {BMO_OP_SLOT_INT, "segments"},
1004          {BMO_OP_SLOT_FLT, "diameter1"}, /* diameter of one end */
1005          {BMO_OP_SLOT_FLT, "diameter2"}, /* diameter of the opposite */
1006          {BMO_OP_SLOT_FLT, "depth"}, /* distance between ends */
1007          {BMO_OP_SLOT_MAT, "mat"}, /* matrix to multiply the new geometry with-- */
1008          {0, /* null-terminating sentinel */}},
1009         bmo_create_cone_exec,
1010         0,
1011 };
1012
1013 /*
1014  * Creates a circle
1015  */
1016 static BMOpDefine bmo_create_circle_def = {
1017         "create_circle",
1018         {{BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, /* output verts */
1019          {BMO_OP_SLOT_BOOL, "cap_ends"}, /* wheter or not to fill in the ends with faces */
1020          {BMO_OP_SLOT_BOOL, "cap_tris"}, /* fill ends with triangles instead of ngons */
1021          {BMO_OP_SLOT_INT, "segments"},
1022          {BMO_OP_SLOT_FLT, "diameter"}, /* diameter of one end */
1023          {BMO_OP_SLOT_MAT, "mat"}, /* matrix to multiply the new geometry with-- */
1024          {0, /* null-terminating sentinel */}},
1025         bmo_create_circle_exec,
1026         0,
1027 };
1028
1029 /*
1030  * Create Cone
1031  *
1032  * Creates a cone with variable depth at both ends
1033  */
1034 static BMOpDefine bmo_create_cube_def = {
1035         "create_cube",
1036         {{BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, /* output verts */
1037          {BMO_OP_SLOT_FLT, "size"}, /* size of the cube */
1038          {BMO_OP_SLOT_MAT, "mat"}, /* matrix to multiply the new geometry with-- */
1039          {0, /* null-terminating sentinel */}},
1040         bmo_create_cube_exec,
1041         0,
1042 };
1043
1044 /*
1045  * Bevel
1046  *
1047  * Bevels edges and vertices
1048  */
1049 static BMOpDefine bmo_bevel_def = {
1050         "bevel",
1051         {{BMO_OP_SLOT_ELEMENT_BUF, "geom"}, /* input edges and vertices */
1052          {BMO_OP_SLOT_ELEMENT_BUF, "face_spans"}, /* new geometry */
1053          {BMO_OP_SLOT_ELEMENT_BUF, "face_holes"}, /* new geometry */
1054          {BMO_OP_SLOT_BOOL, "use_lengths"}, /* grab edge lengths from a PROP_FLT customdata layer */
1055          {BMO_OP_SLOT_BOOL, "use_even"}, /* corner vert placement: use shell/angle calculations  */
1056          {BMO_OP_SLOT_BOOL, "use_dist"}, /* corner vert placement: evaluate percent as a distance,
1057                                           * modifier uses this. We could do this as another float setting */
1058          {BMO_OP_SLOT_INT, "lengthlayer"}, /* which PROP_FLT layer to us */
1059          {BMO_OP_SLOT_FLT, "percent"}, /* percentage to expand beveled edge */
1060          {0} /* null-terminating sentinel */},
1061         bmo_bevel_exec,
1062         BMO_OP_FLAG_UNTAN_MULTIRES
1063 };
1064
1065 /*
1066  * Beautify Fill
1067  *
1068  * Makes triangle a bit nicer
1069  */
1070 static BMOpDefine bmo_beautify_fill_def = {
1071         "beautify_fill",
1072         {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
1073          {BMO_OP_SLOT_ELEMENT_BUF, "constrain_edges"}, /* edges that can't be flipped */
1074          {BMO_OP_SLOT_ELEMENT_BUF, "geomout"}, /* new flipped faces and edges */
1075          {0} /* null-terminating sentinel */},
1076         bmo_beautify_fill_exec,
1077         BMO_OP_FLAG_UNTAN_MULTIRES
1078 };
1079
1080 /*
1081  * Triangle Fill
1082  *
1083  * Fill edges with triangles
1084  */
1085 static BMOpDefine bmo_triangle_fill_def = {
1086         "triangle_fill",
1087         {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edges */
1088          {BMO_OP_SLOT_ELEMENT_BUF, "geomout"}, /* new faces and edges */
1089          {0} /* null-terminating sentinel */},
1090         bmo_triangle_fill_exec,
1091         BMO_OP_FLAG_UNTAN_MULTIRES
1092 };
1093
1094 /*
1095  * Solidify
1096  *
1097  * Turns a mesh into a shell with thickness
1098  */
1099 static BMOpDefine bmo_solidify_def = {
1100         "solidify",
1101         {{BMO_OP_SLOT_ELEMENT_BUF, "geom"},
1102          {BMO_OP_SLOT_FLT, "thickness"},
1103          {BMO_OP_SLOT_ELEMENT_BUF, "geomout"},
1104          {0}},
1105         bmo_solidify_face_region_exec,
1106         0
1107 };
1108
1109 /*
1110  * Face Inset
1111  *
1112  * Extrudes faces individually.
1113  */
1114 static BMOpDefine bmo_inset_def = {
1115         "inset",
1116         {{BMO_OP_SLOT_ELEMENT_BUF, "faces"},   /* input faces */
1117          {BMO_OP_SLOT_ELEMENT_BUF, "faceout"}, /* output faces */
1118          {BMO_OP_SLOT_BOOL, "use_boundary"},
1119          {BMO_OP_SLOT_BOOL, "use_even_offset"},
1120          {BMO_OP_SLOT_BOOL, "use_relative_offset"},
1121          {BMO_OP_SLOT_FLT, "thickness"},
1122          {BMO_OP_SLOT_FLT, "depth"},
1123          {BMO_OP_SLOT_BOOL, "use_outset"},
1124          {0} /* null-terminating sentinel */},
1125         bmo_inset_exec,
1126         0
1127 };
1128
1129 /*
1130  * Wire Frame
1131  *
1132  * Makes a wire copy of faces.
1133  */
1134 static BMOpDefine bmo_wireframe_def = {
1135         "wireframe",
1136         {{BMO_OP_SLOT_ELEMENT_BUF, "faces"},   /* input faces */
1137          {BMO_OP_SLOT_ELEMENT_BUF, "faceout"}, /* output faces */
1138          {BMO_OP_SLOT_BOOL, "use_boundary"},
1139          {BMO_OP_SLOT_BOOL, "use_even_offset"},
1140          {BMO_OP_SLOT_BOOL, "use_crease"},
1141          {BMO_OP_SLOT_FLT, "thickness"},
1142          {BMO_OP_SLOT_BOOL, "use_relative_offset"},
1143          {BMO_OP_SLOT_FLT, "depth"},
1144          {0} /* null-terminating sentinel */},
1145         bmo_wireframe_exec,
1146         0
1147 };
1148
1149 /*
1150  * Vertex Slide
1151  *
1152  * Translates vertes along an edge
1153  */
1154 static BMOpDefine bmo_slide_vert_def = {
1155         "slide_vert",
1156         {{BMO_OP_SLOT_ELEMENT_BUF, "vert"},
1157          {BMO_OP_SLOT_ELEMENT_BUF, "edge"},
1158          {BMO_OP_SLOT_ELEMENT_BUF, "vertout"},
1159          {BMO_OP_SLOT_FLT, "distance_t"},
1160          {0} /* null-terminating sentinel */},
1161         bmo_slide_vert_exec,
1162         BMO_OP_FLAG_UNTAN_MULTIRES
1163 };
1164
1165 #ifdef WITH_BULLET
1166 /*
1167  * Convex Hull
1168  *
1169  * Builds a convex hull from the vertices in 'input'.
1170  *
1171  * If 'use_existing_faces' is true, the hull will not output triangles
1172  * that are covered by a pre-existing face.
1173  *
1174  * All hull vertices, faces, and edges are added to 'geomout'. Any
1175  * input elements that end up inside the hull (i.e. are not used by an
1176  * output face) are added to the 'interior_geom' slot. The
1177  * 'unused_geom' slot will contain all interior geometry that is
1178  * completely unused. Lastly, 'holes_geom' contains edges and faces
1179  * that were in the input and are part of the hull.
1180  */
1181 static BMOpDefine bmo_convex_hull_def = {
1182         "convex_hull",
1183         {{BMO_OP_SLOT_ELEMENT_BUF, "input"},
1184          {BMO_OP_SLOT_BOOL, "use_existing_faces"},
1185
1186          /* Outputs */
1187          {BMO_OP_SLOT_ELEMENT_BUF, "geomout"},
1188          {BMO_OP_SLOT_ELEMENT_BUF, "interior_geom"},
1189          {BMO_OP_SLOT_ELEMENT_BUF, "unused_geom"},
1190          {BMO_OP_SLOT_ELEMENT_BUF, "holes_geom"},
1191          {0} /* null-terminating sentinel */},
1192         bmo_convex_hull_exec,
1193         0
1194 };
1195 #endif
1196
1197 /*
1198  * Symmetrize
1199  *
1200  * Mekes the mesh elements in the "input" slot symmetrical. Unlike
1201  * normal mirroring, it only copies in one direction, as specified by
1202  * the "direction" slot. The edges and faces that cross the plane of
1203  * symmetry are split as needed to enforce symmetry.
1204  *
1205  * All new vertices, edges, and faces are added to the "geomout" slot.
1206  */
1207 static BMOpDefine bmo_symmetrize_def = {
1208         "symmetrize",
1209         {{BMO_OP_SLOT_ELEMENT_BUF, "input"},
1210          {BMO_OP_SLOT_INT, "direction"},
1211
1212          /* Outputs */
1213          {BMO_OP_SLOT_ELEMENT_BUF, "geomout"},
1214
1215          {0} /* null-terminating sentinel */},
1216         bmo_symmetrize_exec,
1217         0
1218 };
1219
1220 BMOpDefine *opdefines[] = {
1221         &bmo_automerge_def,
1222         &bmo_average_vert_facedata_def,
1223         &bmo_beautify_fill_def,
1224         &bmo_bevel_def,
1225         &bmo_bisect_edges_def,
1226         &bmo_bmesh_to_mesh_def,
1227         &bmo_bridge_loops_def,
1228         &bmo_collapse_def,
1229         &bmo_collapse_uvs_def,
1230         &bmo_connect_verts_def,
1231         &bmo_contextual_create_def,
1232 #ifdef WITH_BULLET
1233         &bmo_convex_hull_def,
1234 #endif
1235         &bmo_create_circle_def,
1236         &bmo_create_cone_def,
1237         &bmo_create_cube_def,
1238         &bmo_create_grid_def,
1239         &bmo_create_icosphere_def,
1240         &bmo_create_monkey_def,
1241         &bmo_create_uvsphere_def,
1242         &bmo_create_vert_def,
1243         &bmo_delete_def,
1244         &bmo_dissolve_edge_loop_def,
1245         &bmo_dissolve_edges_def,
1246         &bmo_dissolve_faces_def,
1247         &bmo_dissolve_limit_def,
1248         &bmo_dissolve_verts_def,
1249         &bmo_duplicate_def,
1250         &bmo_edgenet_fill_def,
1251         &bmo_edgenet_prepare_def,
1252         &bmo_extrude_discrete_faces_def,
1253         &bmo_extrude_edge_only_def,
1254         &bmo_extrude_face_region_def,
1255         &bmo_extrude_vert_indiv_def,
1256         &bmo_find_doubles_def,
1257         &bmo_inset_def,
1258         &bmo_join_triangles_def,
1259         &bmo_mesh_to_bmesh_def,
1260         &bmo_mirror_def,
1261         &bmo_object_load_bmesh_def,
1262         &bmo_pointmerge_def,
1263         &bmo_pointmerge_facedata_def,
1264         &bmo_recalc_face_normals_def,
1265         &bmo_region_extend_def,
1266         &bmo_remove_doubles_def,
1267         &bmo_reverse_colors_def,
1268         &bmo_reverse_faces_def,
1269         &bmo_reverse_uvs_def,
1270         &bmo_rotate_colors_def,
1271         &bmo_rotate_def,
1272         &bmo_rotate_edges_def,
1273         &bmo_rotate_uvs_def,
1274         &bmo_scale_def,
1275         &bmo_shortest_path_def,
1276         &bmo_similar_edges_def,
1277         &bmo_similar_faces_def,
1278         &bmo_similar_verts_def,
1279         &bmo_slide_vert_def,
1280         &bmo_smooth_vert_def,
1281         &bmo_solidify_def,
1282         &bmo_spin_def,
1283         &bmo_split_def,
1284         &bmo_split_edges_def,
1285         &bmo_subdivide_edges_def,
1286         &bmo_symmetrize_def,
1287         &bmo_transform_def,
1288         &bmo_translate_def,
1289         &bmo_triangle_fill_def,
1290         &bmo_triangulate_def,
1291         &bmo_unsubdivide_def,
1292         &bmo_weld_verts_def,
1293         &bmo_wireframe_def,
1294
1295 };
1296
1297 int bmesh_total_ops = (sizeof(opdefines) / sizeof(void *));