096c307d9184f40be9428cd4622b5030db659a03
[blender-staging.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. verts.out), for double-type slots, use the two type names plus "out",
51  * (e.g. vertfaces.out), for three-type slots, use geom.  note that you can also
52  * use more esoteric names (e.g. geom_skirt.out) 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_operators_private.h"
61
62 /* The formatting of these bmesh operators is parsed by
63  * 'doc/python_api/rst_from_bmesh_opdefines.py'
64  * for use in python docs, so reStructuredText may be used
65  * rather then doxygen syntax.
66  *
67  * template (py quotes used because nested comments don't work
68  * on all C compilers):
69  *
70  * """
71  * Region Extend.
72  *
73  * paragraph1, Extends bleh bleh bleh.
74  * Bleh Bleh bleh.
75  *
76  * Another paragraph.
77  *
78  * Another paragraph.
79  * """
80  *
81  * so the first line is the "title" of the bmop.
82  * subsequent line blocks separated by blank lines
83  * are paragraphs.  individual descriptions of slots
84  * are extracted from comments next to them.
85  *
86  * eg:
87  *     {BMO_OP_SLOT_ELEMENT_BUF, "geom.out"},  """ output slot, boundary region """
88  *
89  * ... or:
90  *
91  * """ output slot, boundary region """
92  *     {BMO_OP_SLOT_ELEMENT_BUF, "geom.out"},
93  *
94  * Both are acceptable.
95  * note that '//' comments are ignored.
96  */
97
98 /*
99  * Vertex Smooth.
100  *
101  * Smooths vertices by using a basic vertex averaging scheme.
102  */
103 static BMOpDefine bmo_smooth_vert_def = {
104         "smooth_vert",
105         /* slots_in */
106         {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},    /* input vertices */
107          {"factor", BMO_OP_SLOT_FLT},           /* smoothing factor */
108          {"mirror_clip_x", BMO_OP_SLOT_BOOL},   /* set vertices close to the x axis before the operation to 0 */
109          {"mirror_clip_y", BMO_OP_SLOT_BOOL},   /* set vertices close to the y axis before the operation to 0 */
110          {"mirror_clip_z", BMO_OP_SLOT_BOOL},   /* set vertices close to the z axis before the operation to 0 */
111          {"clip_dist",  BMO_OP_SLOT_FLT},       /* clipping threshold for the above three slots */
112          {"use_axis_x", BMO_OP_SLOT_BOOL},      /* smooth vertices along X axis */
113          {"use_axis_y", BMO_OP_SLOT_BOOL},      /* smooth vertices along Y axis */
114          {"use_axis_z", BMO_OP_SLOT_BOOL},      /* smooth vertices along Z axis */
115         {{'\0'}},
116         },
117         {{{'\0'}}},  /* no output */
118         bmo_smooth_vert_exec,
119         (BMO_OPTYPE_FLAG_NORMALS_CALC),
120 };
121
122 /*
123  * Vertext Smooth Laplacian.
124  *
125  * Smooths vertices by using Laplacian smoothing propose by.
126  * Desbrun, et al. Implicit Fairing of Irregular Meshes using Diffusion and Curvature Flow.
127  */
128 static BMOpDefine bmo_smooth_laplacian_vert_def = {
129         "smooth_laplacian_vert",
130         /* slots_in */
131         {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},    /* input vertices */
132          {"lambda_factor", BMO_OP_SLOT_FLT},           /* lambda param */
133          {"lambda_border", BMO_OP_SLOT_FLT},    /* lambda param in border */
134          {"use_x", BMO_OP_SLOT_BOOL},           /* Smooth object along X axis */
135          {"use_y", BMO_OP_SLOT_BOOL},           /* Smooth object along Y axis */
136          {"use_z", BMO_OP_SLOT_BOOL},           /* Smooth object along Z axis */
137          {"preserve_volume", BMO_OP_SLOT_BOOL}, /* Apply volume preservation after smooth */
138         {{'\0'}},
139         },
140         {{{'\0'}}},  /* no output */
141         bmo_smooth_laplacian_vert_exec,
142         (BMO_OPTYPE_FLAG_NORMALS_CALC),
143 };
144
145 /*
146  * Right-Hand Faces.
147  *
148  * Computes an "outside" normal for the specified input faces.
149  */
150 static BMOpDefine bmo_recalc_face_normals_def = {
151         "recalc_face_normals",
152         /* slots_in */
153         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
154          {{'\0'}},
155         },
156         {{{'\0'}}},  /* no output */
157         bmo_recalc_face_normals_exec,
158         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
159          BMO_OPTYPE_FLAG_NORMALS_CALC),
160 };
161
162 /*
163  * Planar Faces.
164  *
165  * Iteratively flatten faces.
166  */
167 static BMOpDefine bmo_planar_faces_def = {
168         "planar_faces",
169         /* slots_in */
170         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},    /* input geometry. */
171          {"iterations", BMO_OP_SLOT_INT},
172          {"factor", BMO_OP_SLOT_FLT},           /* planar factor */
173          {{'\0'}},
174         },
175         /* slots_out */
176         {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* output slot, computed boundary geometry. */
177          {{'\0'}},
178         },
179         bmo_planar_faces_exec,
180         (BMO_OPTYPE_FLAG_SELECT_FLUSH |
181          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
182 };
183
184 /*
185  * Region Extend.
186  *
187  * used to implement the select more/less tools.
188  * this puts some geometry surrounding regions of
189  * geometry in geom into geom.out.
190  *
191  * if use_faces is 0 then geom.out spits out verts and edges,
192  * otherwise it spits out faces.
193  */
194 static BMOpDefine bmo_region_extend_def = {
195         "region_extend",
196         /* slots_in */
197         {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},     /* input geometry */
198          {"use_contract", BMO_OP_SLOT_BOOL},    /* find boundary inside the regions, not outside. */
199          {"use_faces", BMO_OP_SLOT_BOOL},       /* extend from faces instead of edges */
200          {"use_face_step", BMO_OP_SLOT_BOOL},   /* step over connected faces */
201          {{'\0'}},
202         },
203         /* slots_out */
204         {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* output slot, computed boundary geometry. */
205          {{'\0'}},
206         },
207         bmo_region_extend_exec,
208         (BMO_OPTYPE_FLAG_SELECT_FLUSH |
209          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
210 };
211
212 /*
213  * Edge Rotate.
214  *
215  * Rotates edges topologically.  Also known as "spin edge" to some people.
216  * Simple example: ``[/] becomes [|] then [\]``.
217  */
218 static BMOpDefine bmo_rotate_edges_def = {
219         "rotate_edges",
220         /* slots_in */
221         {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},    /* input edges */
222          {"use_ccw", BMO_OP_SLOT_BOOL},         /* rotate edge counter-clockwise if true, otherwise clockwise */
223          {{'\0'}},
224         },
225         /* slots_out */
226         {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* newly spun edges */
227          {{'\0'}},
228         },
229         bmo_rotate_edges_exec,
230         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
231          BMO_OPTYPE_FLAG_NORMALS_CALC |
232          BMO_OPTYPE_FLAG_SELECT_FLUSH |
233          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
234 };
235
236 /*
237  * Reverse Faces.
238  *
239  * Reverses the winding (vertex order) of faces.
240  * This has the effect of flipping the normal.
241  */
242 static BMOpDefine bmo_reverse_faces_def = {
243         "reverse_faces",
244         /* slots_in */
245         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},    /* input faces */
246          {{'\0'}},
247         },
248         {{{'\0'}}},  /* no output */
249         bmo_reverse_faces_exec,
250         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
251          BMO_OPTYPE_FLAG_NORMALS_CALC),
252 };
253
254 /*
255  * Edge Bisect.
256  *
257  * Splits input edges (but doesn't do anything else).
258  * This creates a 2-valence vert.
259  */
260 static BMOpDefine bmo_bisect_edges_def = {
261         "bisect_edges",
262         /* slots_in */
263         {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
264          {"cuts", BMO_OP_SLOT_INT}, /* number of cuts */
265          {"edge_percents", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_FLT}},
266          {{'\0'}},
267         },
268         /* slots_out */
269         {{"geom_split.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* newly created vertices and edges */
270          {{'\0'}},
271         },
272         bmo_bisect_edges_exec,
273         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
274          BMO_OPTYPE_FLAG_NORMALS_CALC |
275          BMO_OPTYPE_FLAG_SELECT_FLUSH |
276          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
277 };
278
279 /*
280  * Mirror.
281  *
282  * Mirrors geometry along an axis.  The resulting geometry is welded on using
283  * merge_dist.  Pairs of original/mirrored vertices are welded using the merge_dist
284  * parameter (which defines the minimum distance for welding to happen).
285  */
286 static BMOpDefine bmo_mirror_def = {
287         "mirror",
288         /* slots_in */
289         {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},     /* input geometry */
290          {"matrix",          BMO_OP_SLOT_MAT},   /* matrix defining the mirror transformation */
291          {"merge_dist",      BMO_OP_SLOT_FLT},   /* maximum distance for merging.  does no merging if 0. */
292          {"axis",            BMO_OP_SLOT_INT},   /* the axis to use, 0, 1, or 2 for x, y, z */
293          {"mirror_u",        BMO_OP_SLOT_BOOL},  /* mirror UVs across the u axis */
294          {"mirror_v",        BMO_OP_SLOT_BOOL},  /* mirror UVs across the v axis */
295          {{'\0'}},
296         },
297         /* slots_out */
298         {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* output geometry, mirrored */
299          {{'\0'}},
300         },
301         bmo_mirror_exec,
302         (BMO_OPTYPE_FLAG_NORMALS_CALC |
303          BMO_OPTYPE_FLAG_SELECT_FLUSH |
304          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
305 };
306
307 /*
308  * Find Doubles.
309  *
310  * Takes input verts and find vertices they should weld to.
311  * Outputs a mapping slot suitable for use with the weld verts bmop.
312  *
313  * If keep_verts is used, vertices outside that set can only be merged
314  * with vertices in that set.
315  */
316 static BMOpDefine bmo_find_doubles_def = {
317         "find_doubles",
318         /* slots_in */
319         {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
320          {"keep_verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* list of verts to keep */
321          {"dist",         BMO_OP_SLOT_FLT}, /* minimum distance */
322          {{'\0'}},
323         },
324         /* slots_out */
325         {{"targetmap.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
326          {{'\0'}},
327         },
328         bmo_find_doubles_exec,
329         (BMO_OPTYPE_FLAG_NOP),
330 };
331
332 /*
333  * Remove Doubles.
334  *
335  * Finds groups of vertices closer then dist and merges them together,
336  * using the weld verts bmop.
337  */
338 static BMOpDefine bmo_remove_doubles_def = {
339         "remove_doubles",
340         /* slots_in */
341         {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input verts */
342          {"dist",         BMO_OP_SLOT_FLT}, /* minimum distance */
343          {{'\0'}},
344         },
345         {{{'\0'}}},  /* no output */
346         bmo_remove_doubles_exec,
347         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
348          BMO_OPTYPE_FLAG_NORMALS_CALC |
349          BMO_OPTYPE_FLAG_SELECT_FLUSH |
350          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
351 };
352
353 /*
354  * Auto Merge.
355  *
356  * Finds groups of vertices closer then **dist** and merges them together,
357  * using the weld verts bmop.  The merges must go from a vert not in
358  * **verts** to one in **verts**.
359  */
360 static BMOpDefine bmo_automerge_def = {
361         "automerge",
362         /* slots_in */
363         {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input verts */
364          {"dist",         BMO_OP_SLOT_FLT}, /* minimum distance */
365          {{'\0'}},
366         },
367         {{{'\0'}}},  /* no output */
368         bmo_automerge_exec,
369         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
370          BMO_OPTYPE_FLAG_NORMALS_CALC |
371          BMO_OPTYPE_FLAG_SELECT_FLUSH |
372          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
373 };
374
375 /*
376  * Collapse Connected.
377  *
378  * Collapses connected vertices
379  */
380 static BMOpDefine bmo_collapse_def = {
381         "collapse",
382         /* slots_in */
383         {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
384          {"uvs", BMO_OP_SLOT_BOOL}, /* also collapse UVs and such */
385          {{'\0'}},
386         },
387         {{{'\0'}}},  /* no output */
388         bmo_collapse_exec,
389         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
390          BMO_OPTYPE_FLAG_NORMALS_CALC |
391          BMO_OPTYPE_FLAG_SELECT_FLUSH |
392          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
393 };
394
395 /*
396  * Face-Data Point Merge.
397  *
398  * Merge uv/vcols at a specific vertex.
399  */
400 static BMOpDefine bmo_pointmerge_facedata_def = {
401         "pointmerge_facedata",
402         /* slots_in */
403         {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},    /* input vertices */
404          {"vert_snap", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE}},    /* snap vertex */
405          {{'\0'}},
406         },
407         {{{'\0'}}},  /* no output */
408         bmo_pointmerge_facedata_exec,
409         (BMO_OPTYPE_FLAG_NOP),
410 };
411
412 /*
413  * Average Vertices Facevert Data.
414  *
415  * Merge uv/vcols associated with the input vertices at
416  * the bounding box center. (I know, it's not averaging but
417  * the vert_snap_to_bb_center is just too long).
418  */
419 static BMOpDefine bmo_average_vert_facedata_def = {
420         "average_vert_facedata",
421         /* slots_in */
422         {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
423          {{'\0'}},
424         },
425         {{{'\0'}}},  /* no output */
426         bmo_average_vert_facedata_exec,
427         (BMO_OPTYPE_FLAG_NOP),
428 };
429
430 /*
431  * Point Merge.
432  *
433  * Merge verts together at a point.
434  */
435 static BMOpDefine bmo_pointmerge_def = {
436         "pointmerge",
437         /* slots_in */
438         {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
439          {"merge_co",         BMO_OP_SLOT_VEC},
440          {{'\0'}},
441         },
442         {{{'\0'}}},  /* no output */
443         bmo_pointmerge_exec,
444         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
445          BMO_OPTYPE_FLAG_NORMALS_CALC |
446          BMO_OPTYPE_FLAG_SELECT_FLUSH |
447          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
448 };
449
450 /*
451  * Collapse Connected UV's.
452  *
453  * Collapses connected UV vertices.
454  */
455 static BMOpDefine bmo_collapse_uvs_def = {
456         "collapse_uvs",
457         /* slots_in */
458         {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
459          {{'\0'}},
460         },
461         {{{'\0'}}},  /* no output */
462         bmo_collapse_uvs_exec,
463         (BMO_OPTYPE_FLAG_NOP),
464 };
465
466 /*
467  * Weld Verts.
468  *
469  * Welds verts together (kind-of like remove doubles, merge, etc, all of which
470  * use or will use this bmop).  You pass in mappings from vertices to the vertices
471  * they weld with.
472  */
473 static BMOpDefine bmo_weld_verts_def = {
474         "weld_verts",
475         /* slots_in */
476         /* maps welded vertices to verts they should weld to */
477         {{"targetmap", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
478          {{'\0'}},
479         },
480         {{{'\0'}}},  /* no output */
481         bmo_weld_verts_exec,
482         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
483          BMO_OPTYPE_FLAG_NORMALS_CALC |
484          BMO_OPTYPE_FLAG_SELECT_FLUSH |
485          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
486 };
487
488 /*
489  * Make Vertex.
490  *
491  * Creates a single vertex; this bmop was necessary
492  * for click-create-vertex.
493  */
494 static BMOpDefine bmo_create_vert_def = {
495         "create_vert",
496         /* slots_in */
497         {{"co", BMO_OP_SLOT_VEC},  /* the coordinate of the new vert */
498          {{'\0'}},
499         },
500         /* slots_out */
501         {{"vert.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},  /* the new vert */
502          {{'\0'}},
503         },
504         bmo_create_vert_exec,
505         (BMO_OPTYPE_FLAG_NOP),
506 };
507
508 /*
509  * Join Triangles.
510  *
511  * Tries to intelligently join triangles according
512  * to angle threshold and delimiters.
513  */
514 static BMOpDefine bmo_join_triangles_def = {
515         "join_triangles",
516         /* slots_in */
517         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},    /* input geometry. */
518          {"cmp_seam", BMO_OP_SLOT_BOOL},
519          {"cmp_sharp", BMO_OP_SLOT_BOOL},
520          {"cmp_uvs", BMO_OP_SLOT_BOOL},
521          {"cmp_vcols", BMO_OP_SLOT_BOOL},
522          {"cmp_materials", BMO_OP_SLOT_BOOL},
523          {"angle_face_threshold", BMO_OP_SLOT_FLT},
524          {"angle_shape_threshold", BMO_OP_SLOT_FLT},
525          {{'\0'}},
526         },
527         /* slots_out */
528         {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},  /* joined faces */
529          {{'\0'}},
530         },
531         bmo_join_triangles_exec,
532         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
533          BMO_OPTYPE_FLAG_NORMALS_CALC |
534          BMO_OPTYPE_FLAG_SELECT_FLUSH |
535          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
536 };
537
538 /*
539  * Contextual Create.
540  *
541  * This is basically F-key, it creates
542  * new faces from vertices, makes stuff from edge nets,
543  * makes wire edges, etc.  It also dissolves faces.
544  *
545  * Three verts become a triangle, four become a quad.  Two
546  * become a wire edge.
547  */
548 static BMOpDefine bmo_contextual_create_def = {
549         "contextual_create",
550         /* slots_in */
551         {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},     /* input geometry. */
552          {"mat_nr",         BMO_OP_SLOT_INT},   /* material to use */
553          {"use_smooth",        BMO_OP_SLOT_BOOL}, /* smooth to use */
554          {{'\0'}},
555         },
556         /* slots_out */
557         {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* newly-made face(s) */
558         /* note, this is for stand-alone edges only, not edges which are apart of newly created faces */
559          {"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* newly-made edge(s) */
560          {{'\0'}},
561         },
562         bmo_contextual_create_exec,
563         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
564          BMO_OPTYPE_FLAG_NORMALS_CALC |
565          BMO_OPTYPE_FLAG_SELECT_FLUSH |
566          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
567 };
568
569 /*
570  * Bridge edge loops with faces.
571  */
572 static BMOpDefine bmo_bridge_loops_def = {
573         "bridge_loops",
574         /* slots_in */
575         {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
576          {"use_pairs",          BMO_OP_SLOT_BOOL},
577          {"use_cyclic",         BMO_OP_SLOT_BOOL},
578          {"use_merge",          BMO_OP_SLOT_BOOL},
579          {"merge_factor",       BMO_OP_SLOT_FLT},
580          {"twist_offset",       BMO_OP_SLOT_INT},
581          {{'\0'}},
582         },
583         /* slots_out */
584         {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* new faces */
585          {"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* new edges */
586          {{'\0'}},
587         },
588         bmo_bridge_loops_exec,
589         (BMO_OPTYPE_FLAG_NORMALS_CALC |
590          BMO_OPTYPE_FLAG_SELECT_FLUSH |
591          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
592 };
593
594 /*
595  * Grid Fill.
596  *
597  * Create faces defined by 2 disconnected edge loops (which share edges).
598  */
599 static BMOpDefine bmo_grid_fill_def = {
600         "grid_fill",
601         /* slots_in */
602         {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
603         /* restricts edges to groups.  maps edges to integer */
604          {"mat_nr",         BMO_OP_SLOT_INT},      /* material to use */
605          {"use_smooth",     BMO_OP_SLOT_BOOL},     /* smooth state to use */
606          {"use_interp_simple", BMO_OP_SLOT_BOOL},  /* use simple interpolation */
607          {{'\0'}},
608         },
609         /* slots_out */
610         /* maps new faces to the group numbers they came from */
611         {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},     /* new faces */
612          {{'\0'}},
613         },
614         bmo_grid_fill_exec,
615         (BMO_OPTYPE_FLAG_NORMALS_CALC |
616          BMO_OPTYPE_FLAG_SELECT_FLUSH),
617 };
618
619
620 /*
621  * Fill Holes.
622  *
623  * Fill boundary edges with faces, copying surrounding customdata.
624  */
625 static BMOpDefine bmo_holes_fill_def = {
626         "holes_fill",
627         /* slots_in */
628         {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
629          {"sides",          BMO_OP_SLOT_INT},   /* number of face sides to fill */
630          {{'\0'}},
631         },
632         /* slots_out */
633         /* maps new faces to the group numbers they came from */
634         {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},     /* new faces */
635          {{'\0'}},
636         },
637         bmo_holes_fill_exec,
638         (BMO_OPTYPE_FLAG_NORMALS_CALC |
639          BMO_OPTYPE_FLAG_SELECT_FLUSH),
640 };
641
642
643 /*
644  * Face Attribute Fill.
645  *
646  * Fill in faces with data from adjacent faces.
647  */
648 static BMOpDefine bmo_face_attribute_fill_def = {
649         "face_attribute_fill",
650         /* slots_in */
651         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},     /* input faces */
652          {"use_normals",        BMO_OP_SLOT_BOOL},  /* copy face winding */
653          {"use_data",           BMO_OP_SLOT_BOOL},  /* copy face data */
654          {{'\0'}},
655         },
656         /* slots_out */
657         /* maps new faces to the group numbers they came from */
658         {{"faces_fail.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},     /* faces that could not be handled */
659          {{'\0'}},
660         },
661         bmo_face_attribute_fill_exec,
662         (BMO_OPTYPE_FLAG_NORMALS_CALC),
663 };
664
665 /*
666  * Edge Loop Fill.
667  *
668  * Create faces defined by one or more non overlapping edge loops.
669  */
670 static BMOpDefine bmo_edgeloop_fill_def = {
671         "edgeloop_fill",
672         /* slots_in */
673         {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
674         /* restricts edges to groups.  maps edges to integer */
675          {"mat_nr",         BMO_OP_SLOT_INT},      /* material to use */
676          {"use_smooth",        BMO_OP_SLOT_BOOL},  /* smooth state to use */
677          {{'\0'}},
678         },
679         /* slots_out */
680         /* maps new faces to the group numbers they came from */
681         {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},     /* new faces */
682          {{'\0'}},
683         },
684         bmo_edgeloop_fill_exec,
685         (BMO_OPTYPE_FLAG_NORMALS_CALC |
686          BMO_OPTYPE_FLAG_SELECT_FLUSH),
687 };
688
689
690 /*
691  * Edge Net Fill.
692  *
693  * Create faces defined by enclosed edges.
694  */
695 static BMOpDefine bmo_edgenet_fill_def = {
696         "edgenet_fill",
697         /* slots_in */
698         {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
699          {"mat_nr",          BMO_OP_SLOT_INT},  /* material to use */
700          {"use_smooth",      BMO_OP_SLOT_BOOL}, /* smooth state to use */
701          {"sides",           BMO_OP_SLOT_INT},  /* number of sides */
702          {{'\0'}},
703         },
704         /* slots_out */
705         /* maps new faces to the group numbers they came from */
706         {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},  /* new faces */
707          {{'\0'}},
708         },
709         bmo_edgenet_fill_exec,
710         (BMO_OPTYPE_FLAG_NORMALS_CALC |
711          BMO_OPTYPE_FLAG_SELECT_FLUSH),
712 };
713
714 /*
715  * Edgenet Prepare.
716  *
717  * Identifies several useful edge loop cases and modifies them so
718  * they'll become a face when edgenet_fill is called.  The cases covered are:
719  *
720  * - One single loop; an edge is added to connect the ends
721  * - Two loops; two edges are added to connect the endpoints (based on the
722  *   shortest distance between each endpont).
723  */
724 static BMOpDefine bmo_edgenet_prepare_def = {
725         "edgenet_prepare",
726         /* slots_in */
727         {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},    /* input edges */
728          {{'\0'}},
729         },
730         /* slots_out */
731         {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},  /* new edges */
732          {{'\0'}},
733         },
734         bmo_edgenet_prepare_exec,
735         (BMO_OPTYPE_FLAG_NOP),
736 };
737
738 /*
739  * Rotate.
740  *
741  * Rotate vertices around a center, using a 3x3 rotation matrix.
742  */
743 static BMOpDefine bmo_rotate_def = {
744         "rotate",
745         /* slots_in */
746         {{"cent",            BMO_OP_SLOT_VEC},  /* center of rotation */
747          {"matrix",          BMO_OP_SLOT_MAT},  /* matrix defining rotation */
748          {"verts",           BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},  /* input vertices */
749          {"space",           BMO_OP_SLOT_MAT},  /* matrix to define the space (typically object matrix) */
750          {{'\0'}},
751         },
752         {{{'\0'}}},  /* no output */
753         bmo_rotate_exec,
754         (BMO_OPTYPE_FLAG_NORMALS_CALC),
755 };
756
757 /*
758  * Translate.
759  *
760  * Translate vertices by an offset.
761  */
762 static BMOpDefine bmo_translate_def = {
763         "translate",
764         /* slots_in */
765         {{"vec", BMO_OP_SLOT_VEC},  /* translation offset */
766          {"space", BMO_OP_SLOT_MAT},  /* matrix to define the space (typically object matrix) */
767          {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},  /* input vertices */
768          {{'\0'}},
769         },
770         {{{'\0'}}},  /* no output */
771         bmo_translate_exec,
772         (BMO_OPTYPE_FLAG_NORMALS_CALC),
773 };
774
775 /*
776  * Scale.
777  *
778  * Scales vertices by an offset.
779  */
780 static BMOpDefine bmo_scale_def = {
781         "scale",
782         /* slots_in */
783         {{"vec", BMO_OP_SLOT_VEC},  /* scale factor */
784          {"space", BMO_OP_SLOT_MAT},  /* matrix to define the space (typically object matrix) */
785          {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},  /* input vertices */
786          {{'\0'}},
787         },
788         {{{'\0'}}},  /* no output */
789         bmo_scale_exec,
790         (BMO_OPTYPE_FLAG_NORMALS_CALC),
791 };
792
793
794 /*
795  * Transform.
796  *
797  * Transforms a set of vertices by a matrix.  Multiplies
798  * the vertex coordinates with the matrix.
799  */
800 static BMOpDefine bmo_transform_def = {
801         "transform",
802         /* slots_in */
803         {{"matrix",          BMO_OP_SLOT_MAT},  /* transform matrix */
804          {"space",           BMO_OP_SLOT_MAT},  /* matrix to define the space (typically object matrix) */
805          {"verts",           BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},  /* input vertices */
806          {{'\0'}},
807         },
808         {{{'\0'}}},  /* no output */
809         bmo_transform_exec,
810         (BMO_OPTYPE_FLAG_NORMALS_CALC),
811 };
812
813 /*
814  * Object Load BMesh.
815  *
816  * Loads a bmesh into an object/mesh.  This is a "private"
817  * bmop.
818  */
819 static BMOpDefine bmo_object_load_bmesh_def = {
820         "object_load_bmesh",
821         /* slots_in */
822         {{"scene", BMO_OP_SLOT_PTR, {BMO_OP_SLOT_SUBTYPE_PTR_SCENE}},
823          {"object", BMO_OP_SLOT_PTR, {BMO_OP_SLOT_SUBTYPE_PTR_OBJECT}},
824          {{'\0'}},
825         },
826         {{{'\0'}}},  /* no output */
827         bmo_object_load_bmesh_exec,
828         (BMO_OPTYPE_FLAG_NOP),
829 };
830
831
832 /*
833  * BMesh to Mesh.
834  *
835  * Converts a bmesh to a Mesh.  This is reserved for exiting editmode.
836  */
837 static BMOpDefine bmo_bmesh_to_mesh_def = {
838         "bmesh_to_mesh",
839         /* slots_in */
840         {
841         /* pointer to a mesh structure to fill in */
842          {"mesh", BMO_OP_SLOT_PTR, {BMO_OP_SLOT_SUBTYPE_PTR_MESH}},
843         /* pointer to an object structure */
844          {"object", BMO_OP_SLOT_PTR, {BMO_OP_SLOT_SUBTYPE_PTR_OBJECT}},
845          {"skip_tessface", BMO_OP_SLOT_BOOL},  /* don't calculate mfaces */
846          {{'\0'}},
847         },
848         {{{'\0'}}},  /* no output */
849         bmo_bmesh_to_mesh_exec,
850         (BMO_OPTYPE_FLAG_NOP),
851 };
852
853 /*
854  * Mesh to BMesh.
855  *
856  * Load the contents of a mesh into the bmesh.  this bmop is private, it's
857  * reserved exclusively for entering editmode.
858  */
859 static BMOpDefine bmo_mesh_to_bmesh_def = {
860         "mesh_to_bmesh",
861         /* slots_in */
862         {
863         /* pointer to a Mesh structure */
864          {"mesh", BMO_OP_SLOT_PTR, {BMO_OP_SLOT_SUBTYPE_PTR_MESH}},
865         /* pointer to an Object structure */
866          {"object", BMO_OP_SLOT_PTR, {BMO_OP_SLOT_SUBTYPE_PTR_OBJECT}},
867          {"use_shapekey", BMO_OP_SLOT_BOOL},  /* load active shapekey coordinates into verts */
868          {{'\0'}},
869         },
870         {{{'\0'}}},  /* no output */
871         bmo_mesh_to_bmesh_exec,
872         (BMO_OPTYPE_FLAG_NOP),
873 };
874
875 /*
876  * Individual Face Extrude.
877  *
878  * Extrudes faces individually.
879  */
880 static BMOpDefine bmo_extrude_discrete_faces_def = {
881         "extrude_discrete_faces",
882         /* slots_in */
883         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},     /* input faces */
884          {"use_select_history", BMO_OP_SLOT_BOOL},  /* pass to duplicate */
885          {{'\0'}},
886         },
887         /* slots_out */
888         {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},   /* output faces */
889          {{'\0'}},
890         },
891         bmo_extrude_discrete_faces_exec,
892         (BMO_OPTYPE_FLAG_NORMALS_CALC),
893 };
894
895 /*
896  * Extrude Only Edges.
897  *
898  * Extrudes Edges into faces, note that this is very simple, there's no fancy
899  * winged extrusion.
900  */
901 static BMOpDefine bmo_extrude_edge_only_def = {
902         "extrude_edge_only",
903         /* slots_in */
904         {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},    /* input vertices */
905          {"use_select_history", BMO_OP_SLOT_BOOL},  /* pass to duplicate */
906          {{'\0'}},
907         },
908         /* slots_out */
909         {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},  /* output geometry */
910          {{'\0'}},
911         },
912         bmo_extrude_edge_only_exec,
913         (BMO_OPTYPE_FLAG_NORMALS_CALC),
914 };
915
916 /*
917  * Individual Vertex Extrude.
918  *
919  * Extrudes wire edges from vertices.
920  */
921 static BMOpDefine bmo_extrude_vert_indiv_def = {
922         "extrude_vert_indiv",
923         /* slots_in */
924         {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},    /* input vertices */
925          {"use_select_history", BMO_OP_SLOT_BOOL},  /* pass to duplicate */
926          {{'\0'}},
927         },
928         /* slots_out */
929         {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},  /* output wire edges */
930          {"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},  /* output vertices */
931          {{'\0'}},
932         },
933         bmo_extrude_vert_indiv_exec,
934         (BMO_OPTYPE_FLAG_SELECT_FLUSH),
935 };
936
937 /*
938  * Connect Verts.
939  *
940  * Split faces by adding edges that connect **verts**.
941  */
942 static BMOpDefine bmo_connect_verts_def = {
943         "connect_verts",
944         /* slots_in */
945         {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},
946          {"faces_exclude", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
947          {"check_degenerate", BMO_OP_SLOT_BOOL},  /* prevent splits with overlaps & intersections */
948          {{'\0'}},
949         },
950         /* slots_out */
951         {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
952          {{'\0'}},
953         },
954         bmo_connect_verts_exec,
955         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
956          BMO_OPTYPE_FLAG_NORMALS_CALC |
957          BMO_OPTYPE_FLAG_SELECT_FLUSH),
958 };
959
960 /*
961  * Connect Verts to form Convex Faces.
962  *
963  * Ensures all faces are convex **faces**.
964  */
965 static BMOpDefine bmo_connect_verts_concave_def = {
966         "connect_verts_concave",
967         /* slots_in */
968         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
969          {{'\0'}},
970         },
971         /* slots_out */
972         {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
973          {"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
974          {{'\0'}},
975         },
976         bmo_connect_verts_concave_exec,
977         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
978          BMO_OPTYPE_FLAG_NORMALS_CALC |
979          BMO_OPTYPE_FLAG_SELECT_FLUSH),
980 };
981
982 /*
983  * Connect Verts Across non Planer Faces.
984  *
985  * Split faces by connecting edges along non planer **faces**.
986  */
987 static BMOpDefine bmo_connect_verts_nonplanar_def = {
988         "connect_verts_nonplanar",
989         /* slots_in */
990         {{"angle_limit", BMO_OP_SLOT_FLT}, /* total rotation angle (radians) */
991          {"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
992          {{'\0'}},
993         },
994         /* slots_out */
995         {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
996          {"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
997          {{'\0'}},
998         },
999         bmo_connect_verts_nonplanar_exec,
1000         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
1001          BMO_OPTYPE_FLAG_NORMALS_CALC |
1002          BMO_OPTYPE_FLAG_SELECT_FLUSH),
1003 };
1004
1005 /*
1006  * Connect Verts.
1007  *
1008  * Split faces by adding edges that connect **verts**.
1009  */
1010 static BMOpDefine bmo_connect_vert_pair_def = {
1011         "connect_vert_pair",
1012         /* slots_in */
1013         {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},
1014          {"verts_exclude", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},
1015          {"faces_exclude", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
1016          {{'\0'}},
1017         },
1018         /* slots_out */
1019         {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
1020          {{'\0'}},
1021         },
1022         bmo_connect_vert_pair_exec,
1023         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
1024          BMO_OPTYPE_FLAG_NORMALS_CALC |
1025          BMO_OPTYPE_FLAG_SELECT_FLUSH),
1026 };
1027
1028
1029 /*
1030  * Extrude Faces.
1031  *
1032  * Extrude operator (does not transform)
1033  */
1034 static BMOpDefine bmo_extrude_face_region_def = {
1035         "extrude_face_region",
1036         /* slots_in */
1037         {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},     /* edges and faces */
1038          {"edges_exclude", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_EMPTY}},
1039          {"use_keep_orig", BMO_OP_SLOT_BOOL},   /* keep original geometry */
1040          {"use_select_history", BMO_OP_SLOT_BOOL},  /* pass to duplicate */
1041          {{'\0'}},
1042         },
1043         /* slots_out */
1044         {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1045          {{'\0'}},
1046         },
1047         bmo_extrude_face_region_exec,
1048         (BMO_OPTYPE_FLAG_NORMALS_CALC),
1049 };
1050
1051 /*
1052  * Dissolve Verts.
1053  */
1054 static BMOpDefine bmo_dissolve_verts_def = {
1055         "dissolve_verts",
1056         /* slots_in */
1057         {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},
1058          {"use_face_split", BMO_OP_SLOT_BOOL},
1059          {"use_boundary_tear", BMO_OP_SLOT_BOOL},
1060          {{'\0'}},
1061         },
1062         {{{'\0'}}},  /* no output */
1063         bmo_dissolve_verts_exec,
1064         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
1065          BMO_OPTYPE_FLAG_NORMALS_CALC |
1066          BMO_OPTYPE_FLAG_SELECT_FLUSH |
1067          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
1068 };
1069
1070 /*
1071  * Dissolve Edges.
1072  */
1073 static BMOpDefine bmo_dissolve_edges_def = {
1074         "dissolve_edges",
1075         /* slots_in */
1076         {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
1077          {"use_verts", BMO_OP_SLOT_BOOL},  /* dissolve verts left between only 2 edges. */
1078          {"use_face_split", BMO_OP_SLOT_BOOL},
1079          {{'\0'}},
1080         },
1081         /* slots_out */
1082         {{"region.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
1083          {{'\0'}},
1084         },
1085         bmo_dissolve_edges_exec,
1086         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
1087          BMO_OPTYPE_FLAG_NORMALS_CALC |
1088          BMO_OPTYPE_FLAG_SELECT_FLUSH |
1089          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
1090 };
1091
1092 /*
1093  * Dissolve Faces.
1094  */
1095 static BMOpDefine bmo_dissolve_faces_def = {
1096         "dissolve_faces",
1097         /* slots_in */
1098         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
1099          {"use_verts", BMO_OP_SLOT_BOOL},  /* dissolve verts left between only 2 edges. */
1100          {{'\0'}},
1101         },
1102         /* slots_out */
1103         {{"region.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
1104          {{'\0'}},
1105         },
1106         bmo_dissolve_faces_exec,
1107         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
1108          BMO_OPTYPE_FLAG_NORMALS_CALC |
1109          BMO_OPTYPE_FLAG_SELECT_FLUSH |
1110          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
1111 };
1112
1113 /*
1114  * Limited Dissolve.
1115  *
1116  * Dissolve planar faces and co-linear edges.
1117  */
1118 static BMOpDefine bmo_dissolve_limit_def = {
1119         "dissolve_limit",
1120         /* slots_in */
1121         {{"angle_limit", BMO_OP_SLOT_FLT}, /* total rotation angle (radians) */
1122          {"use_dissolve_boundaries", BMO_OP_SLOT_BOOL},
1123          {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},
1124          {"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
1125          {"delimit", BMO_OP_SLOT_INT},
1126          {{'\0'}},
1127         },
1128         /* slots_out */
1129         {{"region.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
1130          {{'\0'}}},
1131         bmo_dissolve_limit_exec,
1132         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
1133          BMO_OPTYPE_FLAG_NORMALS_CALC |
1134          BMO_OPTYPE_FLAG_SELECT_FLUSH |
1135          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
1136 };
1137
1138 /*
1139  * Degenerate Dissolve.
1140  *
1141  * Dissolve edges with no length, faces with no area.
1142  */
1143 static BMOpDefine bmo_dissolve_degenerate_def = {
1144         "dissolve_degenerate",
1145         /* slots_in */
1146         {{"dist", BMO_OP_SLOT_FLT}, /* minimum distance to consider degenerate */
1147          {"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
1148          {{'\0'}},
1149         },
1150         /* slots_out */
1151         {{{'\0'}}},
1152         bmo_dissolve_degenerate_exec,
1153         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
1154          BMO_OPTYPE_FLAG_NORMALS_CALC |
1155          BMO_OPTYPE_FLAG_SELECT_FLUSH |
1156          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
1157 };
1158
1159 /*
1160  * Triangulate.
1161  */
1162 static BMOpDefine bmo_triangulate_def = {
1163         "triangulate",
1164         /* slots_in */
1165         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
1166          {"quad_method", BMO_OP_SLOT_INT},
1167          {"ngon_method", BMO_OP_SLOT_INT},
1168          {{'\0'}},
1169         },
1170         /* slots_out */
1171         {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
1172          {"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
1173          {"face_map.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
1174          {{'\0'}},
1175         },
1176         bmo_triangulate_exec,
1177         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
1178          BMO_OPTYPE_FLAG_NORMALS_CALC |
1179          BMO_OPTYPE_FLAG_SELECT_FLUSH),
1180 };
1181
1182 /*
1183  * Un-Subdivide.
1184  *
1185  * Reduce detail in geometry containing grids.
1186  */
1187 static BMOpDefine bmo_unsubdivide_def = {
1188         "unsubdivide",
1189         /* slots_in */
1190         {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
1191          {"iterations", BMO_OP_SLOT_INT},
1192          {{'\0'}},
1193         },
1194         {{{'\0'}}},  /* no output */
1195         bmo_unsubdivide_exec,
1196         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
1197          BMO_OPTYPE_FLAG_NORMALS_CALC |
1198          BMO_OPTYPE_FLAG_SELECT_FLUSH |
1199          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
1200 };
1201
1202 /*
1203  * Subdivide Edges.
1204  *
1205  * Advanced operator for subdividing edges
1206  * with options for face patterns, smoothing and randomization.
1207  */
1208 static BMOpDefine bmo_subdivide_edges_def = {
1209         "subdivide_edges",
1210         /* slots_in */
1211         {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
1212          {"smooth", BMO_OP_SLOT_FLT},
1213          {"smooth_falloff", BMO_OP_SLOT_INT}, /* SUBD_FALLOFF_ROOT and friends */
1214          {"fractal", BMO_OP_SLOT_FLT},
1215          {"along_normal", BMO_OP_SLOT_FLT},
1216          {"cuts", BMO_OP_SLOT_INT},
1217          {"seed", BMO_OP_SLOT_INT},
1218          {"custom_patterns", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL}},  /* uses custom pointers */
1219          {"edge_percents", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_FLT}},
1220
1221          {"quad_corner_type",  BMO_OP_SLOT_INT}, /* quad corner type, see bmesh_operators.h */
1222          {"use_grid_fill", BMO_OP_SLOT_BOOL},   /* fill in fully-selected faces with a grid */
1223          {"use_single_edge", BMO_OP_SLOT_BOOL}, /* tessellate the case of one edge selected in a quad or triangle */
1224          {"use_only_quads", BMO_OP_SLOT_BOOL},  /* only subdivide quads (for loopcut) */
1225          {"use_sphere", BMO_OP_SLOT_BOOL},     /* for making new primitives only */
1226          {"use_smooth_even", BMO_OP_SLOT_BOOL},  /* maintain even offset when smoothing */
1227          {{'\0'}},
1228         },
1229         /* slots_out */
1230         {/* these next three can have multiple types of elements in them */
1231          {"geom_inner.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1232          {"geom_split.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1233          {"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* contains all output geometry */
1234          {{'\0'}},
1235         },
1236         bmo_subdivide_edges_exec,
1237         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
1238          BMO_OPTYPE_FLAG_NORMALS_CALC |
1239          BMO_OPTYPE_FLAG_SELECT_FLUSH |
1240          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
1241 };
1242
1243 /*
1244  * Subdivide Edge-Ring.
1245  *
1246  * Take an edge-ring, and subdivide with interpolation options.
1247  */
1248 static BMOpDefine bmo_subdivide_edgering_def = {
1249         "subdivide_edgering",
1250         /* slots_in */
1251         {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input vertices */
1252          {"interp_mode", BMO_OP_SLOT_INT},
1253          {"smooth", BMO_OP_SLOT_FLT},
1254          {"cuts", BMO_OP_SLOT_INT},
1255          {"profile_shape", BMO_OP_SLOT_INT},
1256          {"profile_shape_factor", BMO_OP_SLOT_FLT},
1257          {{'\0'}},
1258         },
1259         {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
1260          {{'\0'}}},
1261         bmo_subdivide_edgering_exec,
1262         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
1263          BMO_OPTYPE_FLAG_NORMALS_CALC |
1264          BMO_OPTYPE_FLAG_SELECT_FLUSH |
1265          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
1266 };
1267
1268 /*
1269  * Bisect Plane.
1270  *
1271  * Bisects the mesh by a plane (cut the mesh in half).
1272  */
1273 static BMOpDefine bmo_bisect_plane_def = {
1274         "bisect_plane",
1275         /* slots_in */
1276         {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1277          {"dist",         BMO_OP_SLOT_FLT},     /* minimum distance when testing if a vert is exactly on the plane */
1278          {"plane_co", BMO_OP_SLOT_VEC},         /* point on the plane */
1279          {"plane_no", BMO_OP_SLOT_VEC},         /* direction of the plane */
1280          {"use_snap_center", BMO_OP_SLOT_BOOL},  /* snap axis aligned verts to the center */
1281          {"clear_outer",   BMO_OP_SLOT_BOOL},    /* when enabled. remove all geometry on the positive side of the plane */
1282          {"clear_inner",   BMO_OP_SLOT_BOOL},    /* when enabled. remove all geometry on the negative side of the plane */
1283          {{'\0'}},
1284         },
1285         {{"geom_cut.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE}},  /* output new geometry from the cut */
1286          {"geom.out",     BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},  /* input and output geometry (result of cut)  */
1287          {{'\0'}}},
1288         bmo_bisect_plane_exec,
1289         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
1290          BMO_OPTYPE_FLAG_NORMALS_CALC |
1291          BMO_OPTYPE_FLAG_SELECT_FLUSH |
1292          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
1293 };
1294
1295 /*
1296  * Delete Geometry.
1297  *
1298  * Utility operator to delete geometry.
1299  */
1300 static BMOpDefine bmo_delete_def = {
1301         "delete",
1302         /* slots_in */
1303         {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1304          {"context", BMO_OP_SLOT_INT},  /* enum DEL_VERTS ... */
1305          {{'\0'}},
1306         },
1307         {{{'\0'}}},  /* no output */
1308         bmo_delete_exec,
1309         (BMO_OPTYPE_FLAG_NORMALS_CALC |
1310          BMO_OPTYPE_FLAG_SELECT_FLUSH |
1311          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
1312 };
1313
1314 /*
1315  * Duplicate Geometry.
1316  *
1317  * Utility operator to duplicate geometry,
1318  * optionally into a destination mesh.
1319  */
1320 static BMOpDefine bmo_duplicate_def = {
1321         "duplicate",
1322         /* slots_in */
1323         {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1324         /* destination bmesh, if NULL will use current on */
1325          {"dest", BMO_OP_SLOT_PTR, {BMO_OP_SLOT_SUBTYPE_PTR_BMESH}},
1326          {"use_select_history", BMO_OP_SLOT_BOOL},
1327          {{'\0'}},
1328         },
1329         /* slots_out */
1330         {{"geom_orig.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1331          {"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1332         /* facemap maps from source faces to dupe
1333          * faces, and from dupe faces to source faces */
1334          {"vert_map.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
1335          {"edge_map.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
1336          {"face_map.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
1337          {"boundary_map.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
1338          {"isovert_map.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
1339         {{'\0'}},
1340         },
1341         bmo_duplicate_exec,
1342         (BMO_OPTYPE_FLAG_NORMALS_CALC |
1343          BMO_OPTYPE_FLAG_SELECT_FLUSH),
1344 };
1345
1346 /*
1347  * Split Off Geometry.
1348  *
1349  * Disconnect geometry from adjacent edges and faces,
1350  * optionally into a destination mesh.
1351  */
1352 static BMOpDefine bmo_split_def = {
1353         "split",
1354         /* slots_in */
1355         {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1356         /* destination bmesh, if NULL will use current one */
1357          {"dest", BMO_OP_SLOT_PTR, {BMO_OP_SLOT_SUBTYPE_PTR_BMESH}},
1358          {"use_only_faces", BMO_OP_SLOT_BOOL},  /* when enabled. don't duplicate loose verts/edges */
1359          {{'\0'}},
1360         },
1361         /* slots_out */
1362         {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1363          {"boundary_map.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
1364          {"isovert_map.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
1365          {{'\0'}},
1366         },
1367         bmo_split_exec,
1368         (BMO_OPTYPE_FLAG_NORMALS_CALC |
1369          BMO_OPTYPE_FLAG_SELECT_FLUSH),
1370 };
1371
1372 /*
1373  * Spin.
1374  *
1375  * Extrude or duplicate geometry a number of times,
1376  * rotating and possibly translating after each step
1377  */
1378 static BMOpDefine bmo_spin_def = {
1379         "spin",
1380         /* slots_in */
1381         {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1382          {"cent", BMO_OP_SLOT_VEC},             /* rotation center */
1383          {"axis", BMO_OP_SLOT_VEC},             /* rotation axis */
1384          {"dvec", BMO_OP_SLOT_VEC},             /* translation delta per step */
1385          {"angle", BMO_OP_SLOT_FLT},            /* total rotation angle (radians) */
1386          {"space", BMO_OP_SLOT_MAT},            /* matrix to define the space (typically object matrix) */
1387          {"steps", BMO_OP_SLOT_INT},            /* number of steps */
1388          {"use_duplicate", BMO_OP_SLOT_BOOL},   /* duplicate or extrude? */
1389          {{'\0'}},
1390         },
1391         /* slots_out */
1392         {{"geom_last.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* result of last step */
1393          {{'\0'}},
1394         },
1395         bmo_spin_exec,
1396         (BMO_OPTYPE_FLAG_NORMALS_CALC |
1397          BMO_OPTYPE_FLAG_SELECT_FLUSH),
1398 };
1399
1400
1401 /*
1402  * Similar Faces Search.
1403  *
1404  * Find similar faces (area/material/perimeter, ...).
1405  */
1406 static BMOpDefine bmo_similar_faces_def = {
1407         "similar_faces",
1408         /* slots_in */
1409         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},    /* input faces */
1410          {"type", BMO_OP_SLOT_INT},             /* type of selection */
1411          {"thresh", BMO_OP_SLOT_FLT},           /* threshold of selection */
1412          {"compare", BMO_OP_SLOT_INT},          /* comparison method */
1413          {{'\0'}},
1414         },
1415         /* slots_out */
1416         {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},  /* output faces */
1417          {{'\0'}},
1418         },
1419         bmo_similar_faces_exec,
1420         (BMO_OPTYPE_FLAG_SELECT_FLUSH),
1421 };
1422
1423 /*
1424  * Similar Edges Search.
1425  *
1426  *  Find similar edges (length, direction, edge, seam, ...).
1427  */
1428 static BMOpDefine bmo_similar_edges_def = {
1429         "similar_edges",
1430         /* slots_in */
1431         {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},    /* input edges */
1432          {"type", BMO_OP_SLOT_INT},             /* type of selection */
1433          {"thresh", BMO_OP_SLOT_FLT},           /* threshold of selection */
1434          {"compare", BMO_OP_SLOT_INT},          /* comparison method */
1435          {{'\0'}},
1436         },
1437         /* slots_out */
1438         {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},  /* output edges */
1439          {{'\0'}},
1440         },
1441         bmo_similar_edges_exec,
1442         (BMO_OPTYPE_FLAG_SELECT_FLUSH),
1443 };
1444
1445 /*
1446  * Similar Verts Search.
1447  *
1448  * Find similar vertices (normal, face, vertex group, ...).
1449  */
1450 static BMOpDefine bmo_similar_verts_def = {
1451         "similar_verts",
1452         /* slots_in */
1453         {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},    /* input vertices */
1454          {"type", BMO_OP_SLOT_INT},             /* type of selection */
1455          {"thresh", BMO_OP_SLOT_FLT},           /* threshold of selection */
1456          {"compare", BMO_OP_SLOT_INT},          /* comparison method */
1457          {{'\0'}},
1458         },
1459         /* slots_out */
1460         {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},  /* output vertices */
1461          {{'\0'}},
1462         },
1463         bmo_similar_verts_exec,
1464         (BMO_OPTYPE_FLAG_SELECT_FLUSH),
1465 };
1466
1467 /*
1468  * UV Rotation.
1469  *
1470  * Cycle the loop UV's
1471  */
1472 static BMOpDefine bmo_rotate_uvs_def = {
1473         "rotate_uvs",
1474         /* slots_in */
1475         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},    /* input faces */
1476          {"use_ccw", BMO_OP_SLOT_BOOL},         /* rotate counter-clockwise if true, otherwise clockwise */
1477          {{'\0'}},
1478         },
1479         {{{'\0'}}},  /* no output */
1480         bmo_rotate_uvs_exec,
1481         (BMO_OPTYPE_FLAG_NOP),
1482 };
1483
1484 /*
1485  * UV Reverse.
1486  *
1487  * Reverse the UV's
1488  */
1489 static BMOpDefine bmo_reverse_uvs_def = {
1490         "reverse_uvs",
1491         /* slots_in */
1492         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},    /* input faces */
1493          {{'\0'}},
1494         },
1495         {{{'\0'}}},  /* no output */
1496         bmo_reverse_uvs_exec,
1497         (BMO_OPTYPE_FLAG_NOP),
1498 };
1499
1500 /*
1501  * Color Rotation.
1502  *
1503  * Cycle the loop colors
1504  */
1505 static BMOpDefine bmo_rotate_colors_def = {
1506         "rotate_colors",
1507         /* slots_in */
1508         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},    /* input faces */
1509          {"use_ccw", BMO_OP_SLOT_BOOL},         /* rotate counter-clockwise if true, otherwise clockwise */
1510          {{'\0'}},
1511         },
1512         {{{'\0'}}},  /* no output */
1513         bmo_rotate_colors_exec,
1514         (BMO_OPTYPE_FLAG_NOP),
1515 };
1516
1517 /*
1518  * Color Reverse
1519  *
1520  * Reverse the loop colors.
1521  */
1522 static BMOpDefine bmo_reverse_colors_def = {
1523         "reverse_colors",
1524         /* slots_in */
1525         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},    /* input faces */
1526          {{'\0'}},
1527         },
1528         {{{'\0'}}},  /* no output */
1529         bmo_reverse_colors_exec,
1530         (BMO_OPTYPE_FLAG_NOP),
1531 };
1532
1533 /*
1534  * Edge Split.
1535  *
1536  * Disconnects faces along input edges.
1537  */
1538 static BMOpDefine bmo_split_edges_def = {
1539         "split_edges",
1540         /* slots_in */
1541         {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},    /* input edges */
1542          /* needed for vertex rip so we can rip only half an edge at a boundary wich would otherwise split off */
1543          {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},    /* optional tag verts, use to have greater control of splits */
1544          {"use_verts",        BMO_OP_SLOT_BOOL}, /* use 'verts' for splitting, else just find verts to split from edges */
1545          {{'\0'}},
1546         },
1547         /* slots_out */
1548         {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* old output disconnected edges */
1549          {{'\0'}},
1550         },
1551         bmo_split_edges_exec,
1552         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
1553          BMO_OPTYPE_FLAG_NORMALS_CALC |
1554          BMO_OPTYPE_FLAG_SELECT_FLUSH),
1555 };
1556
1557 /*
1558  * Create Grid.
1559  *
1560  * Creates a grid with a variable number of subdivisions
1561  */
1562 static BMOpDefine bmo_create_grid_def = {
1563         "create_grid",
1564         /* slots_in */
1565         {{"x_segments",      BMO_OP_SLOT_INT},  /* number of x segments */
1566          {"y_segments",      BMO_OP_SLOT_INT},  /* number of y segments */
1567          {"size",            BMO_OP_SLOT_FLT},  /* size of the grid */
1568          {"matrix",          BMO_OP_SLOT_MAT},  /* matrix to multiply the new geometry with */
1569          {{'\0'}},
1570         },
1571         /* slots_out */
1572         {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
1573          {{'\0'}},
1574         },
1575         bmo_create_grid_exec,
1576         (BMO_OPTYPE_FLAG_NORMALS_CALC |
1577          BMO_OPTYPE_FLAG_SELECT_FLUSH),
1578 };
1579
1580 /*
1581  * Create UV Sphere.
1582  *
1583  * Creates a grid with a variable number of subdivisions
1584  */
1585 static BMOpDefine bmo_create_uvsphere_def = {
1586         "create_uvsphere",
1587         /* slots_in */
1588         {{"u_segments",      BMO_OP_SLOT_INT}, /* number of u segments */
1589          {"v_segments",      BMO_OP_SLOT_INT}, /* number of v segment */
1590          {"diameter",        BMO_OP_SLOT_FLT}, /* diameter */
1591          {"matrix",          BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */
1592          {{'\0'}},
1593         },
1594         /* slots_out */
1595         {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
1596          {{'\0'}},
1597         },
1598         bmo_create_uvsphere_exec,
1599         (BMO_OPTYPE_FLAG_NORMALS_CALC |
1600          BMO_OPTYPE_FLAG_SELECT_FLUSH),
1601 };
1602
1603 /*
1604  * Create Ico-Sphere.
1605  *
1606  * Creates a grid with a variable number of subdivisions
1607  */
1608 static BMOpDefine bmo_create_icosphere_def = {
1609         "create_icosphere",
1610         /* slots_in */
1611         {{"subdivisions",    BMO_OP_SLOT_INT}, /* how many times to recursively subdivide the sphere */
1612          {"diameter",        BMO_OP_SLOT_FLT}, /* diameter */
1613          {"matrix",          BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */
1614          {{'\0'}},
1615         },
1616         /* slots_out */
1617         {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
1618          {{'\0'}},
1619         },
1620         bmo_create_icosphere_exec,
1621         (BMO_OPTYPE_FLAG_NORMALS_CALC |
1622          BMO_OPTYPE_FLAG_SELECT_FLUSH),
1623 };
1624
1625 /*
1626  * Create Suzanne.
1627  *
1628  * Creates a monkey (standard blender primitive).
1629  */
1630 static BMOpDefine bmo_create_monkey_def = {
1631         "create_monkey",
1632         /* slots_in */
1633         {{"matrix", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */
1634          {{'\0'}},
1635         },
1636         /* slots_out */
1637         {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
1638          {{'\0'}},
1639         },
1640         bmo_create_monkey_exec,
1641         (BMO_OPTYPE_FLAG_NORMALS_CALC |
1642          BMO_OPTYPE_FLAG_SELECT_FLUSH),
1643 };
1644
1645 /*
1646  * Create Cone.
1647  *
1648  * Creates a cone with variable depth at both ends
1649  */
1650 static BMOpDefine bmo_create_cone_def = {
1651         "create_cone",
1652         /* slots_in */
1653         {{"cap_ends",        BMO_OP_SLOT_BOOL},  /* whether or not to fill in the ends with faces */
1654          {"cap_tris",        BMO_OP_SLOT_BOOL},  /* fill ends with triangles instead of ngons */
1655          {"segments",        BMO_OP_SLOT_INT},
1656          {"diameter1",       BMO_OP_SLOT_FLT},  /* diameter of one end */
1657          {"diameter2",       BMO_OP_SLOT_FLT},  /* diameter of the opposite */
1658          {"depth",           BMO_OP_SLOT_FLT},  /* distance between ends */
1659          {"matrix",          BMO_OP_SLOT_MAT},  /* matrix to multiply the new geometry with */
1660          {{'\0'}},
1661         },
1662         /* slots_out */
1663         {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
1664          {{'\0'}},
1665         },
1666         bmo_create_cone_exec,
1667         (BMO_OPTYPE_FLAG_NORMALS_CALC |
1668          BMO_OPTYPE_FLAG_SELECT_FLUSH),
1669 };
1670
1671 /*
1672  * Creates a Circle.
1673  */
1674 static BMOpDefine bmo_create_circle_def = {
1675         "create_circle",
1676         /* slots_in */
1677         {{"cap_ends",        BMO_OP_SLOT_BOOL},  /* whether or not to fill in the ends with faces */
1678          {"cap_tris",        BMO_OP_SLOT_BOOL},  /* fill ends with triangles instead of ngons */
1679          {"segments",        BMO_OP_SLOT_INT},
1680          {"diameter",        BMO_OP_SLOT_FLT},  /* diameter of one end */
1681          {"matrix",          BMO_OP_SLOT_MAT},  /* matrix to multiply the new geometry with */
1682          {{'\0'}},
1683         },
1684         /* slots_out */
1685         {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
1686          {{'\0'}},
1687         },
1688         bmo_create_circle_exec,
1689         (BMO_OPTYPE_FLAG_NORMALS_CALC |
1690          BMO_OPTYPE_FLAG_SELECT_FLUSH),
1691 };
1692
1693 /*
1694  * Create Cube
1695  *
1696  * Creates a cube.
1697  */
1698 static BMOpDefine bmo_create_cube_def = {
1699         "create_cube",
1700         /* slots_in */
1701         {{"size",            BMO_OP_SLOT_FLT},  /* size of the cube */
1702          {"matrix",          BMO_OP_SLOT_MAT},  /* matrix to multiply the new geometry with */
1703          {{'\0'}},
1704         },
1705         /* slots_out */
1706         {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
1707          {{'\0'}},
1708         },
1709         bmo_create_cube_exec,
1710         (BMO_OPTYPE_FLAG_NORMALS_CALC |
1711          BMO_OPTYPE_FLAG_SELECT_FLUSH),
1712 };
1713
1714 /*
1715  * Bevel.
1716  *
1717  * Bevels edges and vertices
1718  */
1719 static BMOpDefine bmo_bevel_def = {
1720         "bevel",
1721         /* slots_in */
1722         {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},     /* input edges and vertices */
1723          {"offset", BMO_OP_SLOT_FLT},           /* amount to offset beveled edge */
1724          {"offset_type", BMO_OP_SLOT_INT},      /* how to measure offset (enum) */
1725          {"segments", BMO_OP_SLOT_INT},         /* number of segments in bevel */
1726          {"profile", BMO_OP_SLOT_FLT},          /* profile shape, 0->1 (.5=>round) */
1727          {"vertex_only", BMO_OP_SLOT_BOOL},     /* only bevel vertices, not edges */
1728          {"clamp_overlap", BMO_OP_SLOT_BOOL},   /* do not allow beveled edges/vertices to overlap each other */
1729          {"material", BMO_OP_SLOT_INT},         /* material for bevel faces, -1 means get from adjacent faces */
1730          {{'\0'}},
1731         },
1732         /* slots_out */
1733         {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
1734          {{'\0'}},
1735         },
1736
1737         bmo_bevel_exec,
1738         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
1739          BMO_OPTYPE_FLAG_NORMALS_CALC |
1740          BMO_OPTYPE_FLAG_SELECT_FLUSH |
1741          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
1742 };
1743
1744 /*
1745  * Beautify Fill.
1746  *
1747  * Rotate edges to create more evenly spaced triangles.
1748  */
1749 static BMOpDefine bmo_beautify_fill_def = {
1750         "beautify_fill",
1751         /* slots_in */
1752         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
1753          {"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* edges that can be flipped */
1754          {"use_restrict_tag", BMO_OP_SLOT_BOOL}, /* restrict edge rotation to mixed tagged vertices */
1755          {"method", BMO_OP_SLOT_INT}, /* method to define what is beautiful */
1756          {{'\0'}},
1757         },
1758         /* slots_out */
1759         {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* new flipped faces and edges */
1760          {{'\0'}},
1761         },
1762         bmo_beautify_fill_exec,
1763         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
1764          BMO_OPTYPE_FLAG_NORMALS_CALC |
1765          BMO_OPTYPE_FLAG_SELECT_FLUSH |
1766          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
1767 };
1768
1769 /*
1770  * Triangle Fill.
1771  *
1772  * Fill edges with triangles
1773  */
1774 static BMOpDefine bmo_triangle_fill_def = {
1775         "triangle_fill",
1776         /* slots_in */
1777         {{"use_beauty", BMO_OP_SLOT_BOOL},
1778          {"use_dissolve", BMO_OP_SLOT_BOOL},  /* dissolve resulting faces */
1779          {"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},    /* input edges */
1780          {"normal", BMO_OP_SLOT_VEC},  /* optionally pass the fill normal to use */
1781          {{'\0'}},
1782         },
1783         /* slots_out */
1784         {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* new faces and edges */
1785          {{'\0'}},
1786         },
1787         bmo_triangle_fill_exec,
1788         (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
1789          BMO_OPTYPE_FLAG_NORMALS_CALC |
1790          BMO_OPTYPE_FLAG_SELECT_FLUSH),
1791 };
1792
1793 /*
1794  * Solidify.
1795  *
1796  * Turns a mesh into a shell with thickness
1797  */
1798 static BMOpDefine bmo_solidify_def = {
1799         "solidify",
1800         /* slots_in */
1801         {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1802          {"thickness", BMO_OP_SLOT_FLT},
1803          {{'\0'}},
1804         },
1805         /* slots_out */
1806         {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1807          {{'\0'}},
1808         },
1809         bmo_solidify_face_region_exec,
1810         (BMO_OPTYPE_FLAG_NORMALS_CALC |
1811          BMO_OPTYPE_FLAG_SELECT_FLUSH),
1812 };
1813
1814 /*
1815  * Face Inset (Individual).
1816  *
1817  * Insets individual faces.
1818  */
1819 static BMOpDefine bmo_inset_individual_def = {
1820         "inset_individual",
1821         /* slots_in */
1822         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},    /* input faces */
1823          {"thickness", BMO_OP_SLOT_FLT},
1824          {"depth", BMO_OP_SLOT_FLT},
1825          {"use_even_offset", BMO_OP_SLOT_BOOL},
1826          {"use_interpolate", BMO_OP_SLOT_BOOL},
1827          {"use_relative_offset", BMO_OP_SLOT_BOOL},
1828          {{'\0'}},
1829         },
1830         /* slots_out */
1831         {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
1832          {{'\0'}},
1833         },
1834         bmo_inset_individual_exec,
1835         /* caller needs to handle BMO_OPTYPE_FLAG_SELECT_FLUSH */
1836         (BMO_OPTYPE_FLAG_NORMALS_CALC),
1837 };
1838
1839 /*
1840  * Face Inset (Regions).
1841  *
1842  * Inset or outset face regions.
1843  */
1844 static BMOpDefine bmo_inset_region_def = {
1845         "inset_region",
1846         /* slots_in */
1847         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},    /* input faces */
1848          {"faces_exclude", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
1849          {"use_boundary", BMO_OP_SLOT_BOOL},
1850          {"use_even_offset", BMO_OP_SLOT_BOOL},
1851          {"use_interpolate", BMO_OP_SLOT_BOOL},
1852          {"use_relative_offset", BMO_OP_SLOT_BOOL},
1853          {"use_edge_rail", BMO_OP_SLOT_BOOL},
1854          {"thickness", BMO_OP_SLOT_FLT},
1855          {"depth", BMO_OP_SLOT_FLT},
1856          {"use_outset", BMO_OP_SLOT_BOOL},
1857          {{'\0'}},
1858         },
1859         /* slots_out */
1860         {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
1861          {{'\0'}},
1862         },
1863         bmo_inset_region_exec,
1864         (BMO_OPTYPE_FLAG_NORMALS_CALC |
1865          BMO_OPTYPE_FLAG_SELECT_FLUSH),
1866 };
1867
1868 /*
1869  * Wire Frame.
1870  *
1871  * Makes a wire-frame copy of faces.
1872  */
1873 static BMOpDefine bmo_wireframe_def = {
1874         "wireframe",
1875         /* slots_in */
1876         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},   /* input faces */
1877          {"thickness", BMO_OP_SLOT_FLT},
1878          {"offset", BMO_OP_SLOT_FLT},
1879          {"use_replace", BMO_OP_SLOT_BOOL},
1880          {"use_boundary", BMO_OP_SLOT_BOOL},
1881          {"use_even_offset", BMO_OP_SLOT_BOOL},
1882          {"use_crease", BMO_OP_SLOT_BOOL},
1883          {"crease_weight", BMO_OP_SLOT_FLT},
1884          {"thickness", BMO_OP_SLOT_FLT},
1885          {"use_relative_offset", BMO_OP_SLOT_BOOL},
1886          {"material_offset", BMO_OP_SLOT_INT},
1887          {{'\0'}},
1888         },
1889         /* slots_out */
1890         {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
1891          {{'\0'}},
1892         },
1893         bmo_wireframe_exec,
1894         (BMO_OPTYPE_FLAG_NORMALS_CALC |
1895          BMO_OPTYPE_FLAG_SELECT_FLUSH |
1896          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
1897 };
1898
1899 /*
1900  * Pokes a face.
1901  *
1902  * Splits a face into a triangle fan.
1903  */
1904 static BMOpDefine bmo_poke_def = {
1905         "poke",
1906         /* slots_in */
1907         {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},   /* input faces */
1908          {"offset", BMO_OP_SLOT_FLT}, /* center vertex offset along normal */
1909          {"center_mode", BMO_OP_SLOT_INT}, /* calculation mode for center vertex */
1910          {"use_relative_offset", BMO_OP_SLOT_BOOL}, /* apply offset */
1911          {{'\0'}},
1912         },
1913         /* slots_out */
1914         {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
1915          {"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
1916          {{'\0'}},
1917         },
1918         bmo_poke_exec,
1919         (BMO_OPTYPE_FLAG_NORMALS_CALC |
1920          BMO_OPTYPE_FLAG_SELECT_FLUSH |
1921          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
1922 };
1923
1924 #ifdef WITH_BULLET
1925 /*
1926  * Convex Hull
1927  *
1928  * Builds a convex hull from the vertices in 'input'.
1929  *
1930  * If 'use_existing_faces' is true, the hull will not output triangles
1931  * that are covered by a pre-existing face.
1932  *
1933  * All hull vertices, faces, and edges are added to 'geom.out'. Any
1934  * input elements that end up inside the hull (i.e. are not used by an
1935  * output face) are added to the 'interior_geom' slot. The
1936  * 'unused_geom' slot will contain all interior geometry that is
1937  * completely unused. Lastly, 'holes_geom' contains edges and faces
1938  * that were in the input and are part of the hull.
1939  */
1940 static BMOpDefine bmo_convex_hull_def = {
1941         "convex_hull",
1942         /* slots_in */
1943         {{"input", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1944          {"use_existing_faces", BMO_OP_SLOT_BOOL},
1945          {{'\0'}},
1946         },
1947         /* slots_out */
1948         {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1949          {"geom_interior.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1950          {"geom_unused.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1951          {"geom_holes.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1952          {{'\0'}},
1953         },
1954         bmo_convex_hull_exec,
1955         (BMO_OPTYPE_FLAG_NORMALS_CALC |
1956          BMO_OPTYPE_FLAG_SELECT_FLUSH |
1957          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
1958 };
1959 #endif
1960
1961 /*
1962  * Symmetrize.
1963  *
1964  * Makes the mesh elements in the "input" slot symmetrical. Unlike
1965  * normal mirroring, it only copies in one direction, as specified by
1966  * the "direction" slot. The edges and faces that cross the plane of
1967  * symmetry are split as needed to enforce symmetry.
1968  *
1969  * All new vertices, edges, and faces are added to the "geom.out" slot.
1970  */
1971 static BMOpDefine bmo_symmetrize_def = {
1972         "symmetrize",
1973         /* slots_in */
1974         {{"input", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1975          {"direction", BMO_OP_SLOT_INT},
1976          {"dist", BMO_OP_SLOT_FLT}, /* minimum distance */
1977          {{'\0'}},
1978         },
1979         /* slots_out */
1980         {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
1981          {{'\0'}},
1982         },
1983         bmo_symmetrize_exec,
1984         (BMO_OPTYPE_FLAG_NORMALS_CALC |
1985          BMO_OPTYPE_FLAG_SELECT_FLUSH |
1986          BMO_OPTYPE_FLAG_SELECT_VALIDATE),
1987 };
1988
1989 const BMOpDefine *bmo_opdefines[] = {
1990         &bmo_automerge_def,
1991         &bmo_average_vert_facedata_def,
1992         &bmo_beautify_fill_def,
1993         &bmo_bevel_def,
1994         &bmo_bisect_edges_def,
1995         &bmo_bmesh_to_mesh_def,
1996         &bmo_bridge_loops_def,
1997         &bmo_collapse_def,
1998         &bmo_collapse_uvs_def,
1999         &bmo_connect_verts_def,
2000         &bmo_connect_verts_concave_def,
2001         &bmo_connect_verts_nonplanar_def,
2002         &bmo_connect_vert_pair_def,
2003         &bmo_contextual_create_def,
2004 #ifdef WITH_BULLET
2005         &bmo_convex_hull_def,
2006 #endif
2007         &bmo_create_circle_def,
2008         &bmo_create_cone_def,
2009         &bmo_create_cube_def,
2010         &bmo_create_grid_def,
2011         &bmo_create_icosphere_def,
2012         &bmo_create_monkey_def,
2013         &bmo_create_uvsphere_def,
2014         &bmo_create_vert_def,
2015         &bmo_delete_def,
2016         &bmo_dissolve_edges_def,
2017         &bmo_dissolve_faces_def,
2018         &bmo_dissolve_verts_def,
2019         &bmo_dissolve_limit_def,
2020         &bmo_dissolve_degenerate_def,
2021         &bmo_duplicate_def,
2022         &bmo_holes_fill_def,
2023         &bmo_face_attribute_fill_def,
2024         &bmo_edgeloop_fill_def,
2025         &bmo_edgenet_fill_def,
2026         &bmo_edgenet_prepare_def,
2027         &bmo_extrude_discrete_faces_def,
2028         &bmo_extrude_edge_only_def,
2029         &bmo_extrude_face_region_def,
2030         &bmo_extrude_vert_indiv_def,
2031         &bmo_find_doubles_def,
2032         &bmo_grid_fill_def,
2033         &bmo_inset_individual_def,
2034         &bmo_inset_region_def,
2035         &bmo_join_triangles_def,
2036         &bmo_mesh_to_bmesh_def,
2037         &bmo_mirror_def,
2038         &bmo_object_load_bmesh_def,
2039         &bmo_pointmerge_def,
2040         &bmo_pointmerge_facedata_def,
2041         &bmo_poke_def,
2042         &bmo_recalc_face_normals_def,
2043         &bmo_planar_faces_def,
2044         &bmo_region_extend_def,
2045         &bmo_remove_doubles_def,
2046         &bmo_reverse_colors_def,
2047         &bmo_reverse_faces_def,
2048         &bmo_reverse_uvs_def,
2049         &bmo_rotate_colors_def,
2050         &bmo_rotate_def,
2051         &bmo_rotate_edges_def,
2052         &bmo_rotate_uvs_def,
2053         &bmo_scale_def,
2054         &bmo_similar_edges_def,
2055         &bmo_similar_faces_def,
2056         &bmo_similar_verts_def,
2057         &bmo_smooth_vert_def,
2058         &bmo_smooth_laplacian_vert_def,
2059         &bmo_solidify_def,
2060         &bmo_spin_def,
2061         &bmo_split_def,
2062         &bmo_split_edges_def,
2063         &bmo_subdivide_edges_def,
2064         &bmo_subdivide_edgering_def,
2065         &bmo_bisect_plane_def,
2066         &bmo_symmetrize_def,
2067         &bmo_transform_def,
2068         &bmo_translate_def,
2069         &bmo_triangle_fill_def,
2070         &bmo_triangulate_def,
2071         &bmo_unsubdivide_def,
2072         &bmo_weld_verts_def,
2073         &bmo_wireframe_def,
2074 };
2075
2076 const int bmo_opdefines_total = ARRAY_SIZE(bmo_opdefines);