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