fix [#30257] bmesh: Rip "V" don't work on end vertex
[blender.git] / source / blender / bmesh / intern / bmesh_opdefines.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * Contributor(s): Joseph Eagar, Geoffrey Bantle, Campbell Barton
19  *
20  * ***** END GPL LICENSE BLOCK *****
21  */
22
23 /** \file blender/bmesh/intern/bmesh_opdefines.c
24  *  \ingroup bmesh
25  *
26  * BMesh operator definitions.
27  *
28  * This file defines (and documents) all bmesh operators (bmops).
29  *
30  * Do not rename any operator or slot names! otherwise you must go
31  * through the code and find all references to them!
32  *
33  * A word on slot names:
34  *
35  * For geometry input slots, the following are valid names:
36  * - verts
37  * - edges
38  * - faces
39  * - edgefacein
40  * - vertfacein
41  * - vertedgein
42  * - vertfacein
43  * - geom
44  *
45  * The basic rules are, for single-type geometry slots, use the plural of the
46  * type name (e.g. edges).  for double-type slots, use the two type names plus
47  * "in" (e.g. edgefacein).  for three-type slots, use geom.
48  *
49  * for output slots, for single-type geometry slots, use the type name plus "out",
50  * (e.g. vertout), for double-type slots, use the two type names plus "out",
51  * (e.g. vertfaceout), for three-type slots, use geom.  note that you can also
52  * use more esohteric names (e.g. skirtout) so long as the comment next to the
53  * slot definition tells you what types of elements are in it.
54  *
55  */
56
57 #include "BLI_utildefines.h"
58
59 #include "bmesh.h"
60 #include "intern/bmesh_private.h"
61
62 /* ok, I'm going to write a little docgen script. so all
63  * bmop comments must conform to the following template/rules:
64  *
65  * template (py quotes used because nested comments don't work
66  * on all C compilers):
67  *
68  * """
69  * Region Extend.
70  *
71  * paragraph1, Extends bleh bleh bleh.
72  * Bleh Bleh bleh.
73  *
74  * Another paragraph.
75  *
76  * Another paragraph.
77  * """
78  *
79  * so the first line is the "title" of the bmop.
80  * subsequent line blocks separated by blank lines
81  * are paragraphs.  individual descriptions of slots
82  * would be extracted from comments
83  * next to them, e.g.
84  *
85  * {BMO_OP_SLOT_ELEMENT_BUF, "geomout"}, //output slot, boundary region
86  *
87  * the doc generator would automatically detect the presence of "output slot"
88  * and flag the slot as an output.  the same happens for "input slot".  also
89  * note that "edges", "faces", "verts", "loops", and "geometry" are valid
90  * substitutions for "slot".
91  *
92  * note that slots default to being input slots.
93  */
94
95 /*
96  * Vertex Smooth
97  *
98  * Smooths vertices by using a basic vertex averaging scheme.
99  */
100 static BMOpDefine bmo_vertexsmooth_def = {
101         "vertexsmooth",
102         {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, //input vertices
103          {BMO_OP_SLOT_BOOL, "mirror_clip_x"}, //set vertices close to the x axis before the operation to 0
104          {BMO_OP_SLOT_BOOL, "mirror_clip_y"}, //set vertices close to the y axis before the operation to 0
105          {BMO_OP_SLOT_BOOL, "mirror_clip_z"}, //set vertices close to the z axis before the operation to 0
106          {BMO_OP_SLOT_FLT, "clipdist"}, //clipping threshod for the above three slots
107         {0} /* null-terminating sentine */,
108         },
109         bmo_vertexsmooth_exec,
110         0
111 };
112
113 /*
114  * Right-Hand Faces
115  *
116  * Computes an "outside" normal for the specified input faces.
117  */
118
119 static BMOpDefine bmo_righthandfaces_def = {
120         "righthandfaces",
121         {{BMO_OP_SLOT_ELEMENT_BUF, "faces"},
122          {BMO_OP_SLOT_BOOL, "do_flip"}, //internal flag, used by bmesh_rationalize_normals
123          {0} /* null-terminating sentine */,
124         },
125         bmo_righthandfaces_exec,
126         BMO_OP_FLAG_UNTAN_MULTIRES,
127 };
128
129 /*
130  * Region Extend
131  *
132  * used to implement the select more/less tools.
133  * this puts some geometry surrounding regions of
134  * geometry in geom into geomout.
135  *
136  * if usefaces is 0 then geomout spits out verts and edges,
137  * otherwise it spits out faces.
138  */
139 static BMOpDefine bmo_regionextend_def = {
140         "regionextend",
141         {{BMO_OP_SLOT_ELEMENT_BUF, "geom"}, //input geometry
142          {BMO_OP_SLOT_ELEMENT_BUF, "geomout"}, //output slot, computed boundary geometry.
143          {BMO_OP_SLOT_BOOL, "constrict"}, //find boundary inside the regions, not outside.
144          {BMO_OP_SLOT_BOOL, "use_faces"}, //extend from faces instead of edges
145          {0} /* null-terminating sentine */,
146         },
147         bmo_regionextend_exec,
148         0
149 };
150
151 /*
152  * Edge Rotate
153  *
154  * Rotates edges topologically.  Also known as "spin edge" to some people.
155  * Simple example: [/] becomes [|] then [\].
156  */
157 static BMOpDefine bmo_edgerotate_def = {
158         "edgerotate",
159         {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, //input edges
160          {BMO_OP_SLOT_ELEMENT_BUF, "edgeout"}, //newly spun edges
161          {BMO_OP_SLOT_BOOL, "ccw"}, //rotate edge counter-clockwise if true, othewise clockwise
162          {0} /* null-terminating sentine */,
163         },
164         bmo_edgerotate_exec,
165         BMO_OP_FLAG_UNTAN_MULTIRES
166 };
167
168 /*
169  * Reverse Faces
170  *
171  * Reverses the winding (vertex order) of faces.  This has the effect of
172  * flipping the normal.
173  */
174 static BMOpDefine bmo_reversefaces_def = {
175         "reversefaces",
176         {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, //input faces
177          {0} /* null-terminating sentine */,
178         },
179         bmo_reversefaces_exec,
180         BMO_OP_FLAG_UNTAN_MULTIRES,
181 };
182
183 /*
184  * Edge Bisect
185  *
186  * Splits input edges (but doesn't do anything else).
187  * This creates a 2-valence vert.
188  */
189 static BMOpDefine bmo_edgebisect_def = {
190         "edgebisect",
191         {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, //input edges
192          {BMO_OP_SLOT_INT, "numcuts"}, //number of cuts
193          {BMO_OP_SLOT_ELEMENT_BUF, "outsplit"}, //newly created vertices and edges
194          {0} /* null-terminating sentine */,
195         },
196         bmo_edgebisect_exec,
197         BMO_OP_FLAG_UNTAN_MULTIRES
198 };
199
200 /*
201  * Mirror
202  *
203  * Mirrors geometry along an axis.  The resulting geometry is welded on using
204  * mergedist.  Pairs of original/mirrored vertices are welded using the mergedist
205  * parameter (which defines the minimum distance for welding to happen).
206  */
207
208 static BMOpDefine bmo_mirror_def = {
209         "mirror",
210         {{BMO_OP_SLOT_ELEMENT_BUF, "geom"}, //input geometry
211          {BMO_OP_SLOT_MAT, "mat"}, //matrix defining the mirror transformation
212          {BMO_OP_SLOT_FLT, "mergedist"}, //maximum distance for merging.  does no merging if 0.
213          {BMO_OP_SLOT_ELEMENT_BUF, "newout"}, //output geometry, mirrored
214          {BMO_OP_SLOT_INT,         "axis"}, //the axis to use, 0, 1, or 2 for x, y, z
215          {BMO_OP_SLOT_BOOL,        "mirror_u"}, //mirror UVs across the u axis
216          {BMO_OP_SLOT_BOOL,        "mirror_v"}, //mirror UVs across the v axis
217          {0, /* null-terminating sentine */}},
218         bmo_mirror_exec,
219         0,
220 };
221
222 /*
223  * Find Doubles
224  *
225  * Takes input verts and find vertices they should weld to.  Outputs a
226  * mapping slot suitable for use with the weld verts bmop.
227  */
228 static BMOpDefine bmo_finddoubles_def = {
229         "finddoubles",
230         {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, //input vertices
231          {BMO_OP_SLOT_ELEMENT_BUF, "keepverts"}, //list of verts to keep
232          {BMO_OP_SLOT_FLT,         "dist"}, //minimum distance
233          {BMO_OP_SLOT_MAPPING, "targetmapout"},
234          {0, /* null-terminating sentine */}},
235         bmo_finddoubles_exec,
236         0,
237 };
238
239 /*
240  * Remove Doubles
241  *
242  * Finds groups of vertices closer then dist and merges them together,
243  * using the weld verts bmop.
244  */
245 static BMOpDefine bmo_removedoubles_def = {
246         "removedoubles",
247         {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, //input verts
248          {BMO_OP_SLOT_FLT,         "dist"}, //minimum distance
249          {0, /* null-terminating sentine */}},
250         bmo_removedoubles_exec,
251         BMO_OP_FLAG_UNTAN_MULTIRES,
252 };
253
254 /*
255  * Auto Merge
256  *
257  * Finds groups of vertices closer then dist and merges them together,
258  * using the weld verts bmop.  The merges must go from a vert not in
259  * verts to one in verts.
260  */
261 static BMOpDefine bmo_automerge_def = {
262         "automerge",
263         {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, //input verts
264          {BMO_OP_SLOT_FLT,         "dist"}, //minimum distance
265          {0, /* null-terminating sentine */}},
266         bmo_automerge_exec,
267         BMO_OP_FLAG_UNTAN_MULTIRES,
268 };
269
270 /*
271  * Collapse Connected
272  *
273  * Collapses connected vertices
274  */
275 static BMOpDefine bmo_collapse_def = {
276         "collapse",
277         {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edge */
278          {0, /* null-terminating sentine */}},
279         bmo_collapse_exec,
280         BMO_OP_FLAG_UNTAN_MULTIRES,
281 };
282
283
284 /*
285  * Facedata point Merge
286  *
287  * Merge uv/vcols at a specific vertex.
288  */
289 static BMOpDefine bmo_pointmerge_facedata_def = {
290         "pointmerge_facedata",
291         {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertice */
292          {BMO_OP_SLOT_ELEMENT_BUF, "snapv"}, /* snap verte */
293          {0, /* null-terminating sentine */}},
294         bmo_pointmerge_facedata_exec,
295         0,
296 };
297
298 /*
299  * Average Vertices Facevert Data
300  *
301  * Merge uv/vcols associated with the input vertices at
302  * the bounding box center. (I know, it's not averaging but
303  * the vert_snap_to_bb_center is just too long).
304  */
305 static BMOpDefine bmo_vert_average_facedata_def = {
306         "vert_average_facedata",
307         {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertice */
308          {0, /* null-terminating sentine */}},
309         bmo_vert_average_facedata_exec,
310         0,
311 };
312
313 /*
314  * Point Merge
315  *
316  * Merge verts together at a point.
317  */
318 static BMOpDefine bmo_pointmerge_def = {
319         "pointmerge",
320         {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertice */
321          {BMO_OP_SLOT_VEC,         "mergeco"},
322          {0, /* null-terminating sentine */}},
323         bmo_pointmerge_exec,
324         BMO_OP_FLAG_UNTAN_MULTIRES,
325 };
326
327 /*
328  * Collapse Connected UVs
329  *
330  * Collapses connected UV vertices.
331  */
332 static BMOpDefine bmo_collapse_uvs_def = {
333         "collapse_uvs",
334         {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edge */
335          {0, /* null-terminating sentine */}},
336         bmo_collapse_uvs_exec,
337         0,
338 };
339
340 /*
341  * Weld Verts
342  *
343  * Welds verts together (kindof like remove doubles, merge, etc, all of which
344  * use or will use this bmop).  You pass in mappings from vertices to the vertices
345  * they weld with.
346  */
347 static BMOpDefine bmo_weldverts_def = {
348         "weldverts",
349         {{BMO_OP_SLOT_MAPPING, "targetmap"}, /* maps welded vertices to verts they should weld to */
350          {0, /* null-terminating sentine */}},
351         bmo_weldverts_exec,
352         BMO_OP_FLAG_UNTAN_MULTIRES,
353 };
354
355 /*
356  * Make Vertex
357  *
358  * Creates a single vertex; this bmop was necessary
359  * for click-create-vertex.
360  */
361 static BMOpDefine bmo_makevert_def = {
362         "makevert",
363         {{BMO_OP_SLOT_VEC, "co"}, //the coordinate of the new vert
364          {BMO_OP_SLOT_ELEMENT_BUF, "newvertout"}, //the new vert
365          {0, /* null-terminating sentine */}},
366         bmo_makevert_exec,
367         0,
368 };
369
370 /*
371  * Join Triangles
372  *
373  * Tries to intelligently join triangles according
374  * to various settings and stuff.
375  */
376 static BMOpDefine bmo_join_triangles_def = {
377         "join_triangles",
378         {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, //input geometry.
379          {BMO_OP_SLOT_ELEMENT_BUF, "faceout"}, //joined faces
380          {BMO_OP_SLOT_BOOL, "cmp_sharp"},
381          {BMO_OP_SLOT_BOOL, "cmp_uvs"},
382          {BMO_OP_SLOT_BOOL, "cmp_vcols"},
383          {BMO_OP_SLOT_BOOL, "cmp_materials"},
384          {BMO_OP_SLOT_FLT, "limit"},
385          {0, /* null-terminating sentine */}},
386         bmo_join_triangles_exec,
387         BMO_OP_FLAG_UNTAN_MULTIRES,
388 };
389
390 /*
391  * Contextual Create
392  *
393  * This is basically fkey, it creates
394  * new faces from vertices, makes stuff from edge nets,
395  * makes wire edges, etc.  It also dissolves
396  * faces.
397  *
398  * Three verts become a triangle, four become a quad.  Two
399  * become a wire edge.
400  */
401 static BMOpDefine bmo_contextual_create_def = {
402         "contextual_create",
403         {{BMO_OP_SLOT_ELEMENT_BUF, "geom"}, //input geometry.
404          {BMO_OP_SLOT_ELEMENT_BUF, "faceout"}, //newly-made face(s)
405          {0, /* null-terminating sentine */}},
406         bmo_contextual_create_exec,
407         BMO_OP_FLAG_UNTAN_MULTIRES,
408 };
409
410 /*
411  * Bridge edge loops with faces
412  */
413 static BMOpDefine bmo_bridge_loops_def = {
414         "bridge_loops",
415         {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edge */
416          {BMO_OP_SLOT_ELEMENT_BUF, "faceout"}, /* new face */
417          {0, /* null-terminating sentine */}},
418         bmo_bridge_loops_exec,
419         0,
420 };
421
422 static BMOpDefine bmo_edgenet_fill_def = {
423         "edgenet_fill",
424         {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edge */
425          {BMO_OP_SLOT_MAPPING,     "restrict"}, /* restricts edges to groups.  maps edges to integer */
426          {BMO_OP_SLOT_BOOL,        "use_restrict"},
427          {BMO_OP_SLOT_BOOL,        "use_fill_check"},
428          {BMO_OP_SLOT_ELEMENT_BUF, "excludefaces"}, /* list of faces to ignore for manifold check */
429          {BMO_OP_SLOT_MAPPING,     "faceout_groupmap"}, /* maps new faces to the group numbers they came fro */
430          {BMO_OP_SLOT_ELEMENT_BUF, "faceout"}, /* new face */
431          {0, /* null-terminating sentine */}},
432         bmo_edgenet_fill_exec,
433         0,
434 };
435
436 /*
437  * Edgenet Prepare
438  *
439  * Identifies several useful edge loop cases and modifies them so
440  * they'll become a face when edgenet_fill is called.  The cases covered are:
441  *
442  * - One single loop; an edge is added to connect the ends
443  * - Two loops; two edges are added to connect the endpoints (based on the
444  *   shortest distance between each endpont).
445  */
446 static BMOpDefine bmo_edgenet_prepare_def = {
447         "edgenet_prepare",
448         {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, //input edges
449          {BMO_OP_SLOT_ELEMENT_BUF, "edgeout"}, //new edges
450          {0, /* null-terminating sentine */}},
451         bmo_edgenet_prepare,
452         0,
453 };
454
455 /*
456  * Rotate
457  *
458  * Rotate vertices around a center, using a 3x3 rotation
459  * matrix.  Equivalent of the old rotateflag function.
460  */
461 static BMOpDefine bmo_rotate_def = {
462         "rotate",
463         {{BMO_OP_SLOT_VEC, "cent"}, //center of rotation
464          {BMO_OP_SLOT_MAT, "mat"}, //matrix defining rotation
465          {BMO_OP_SLOT_ELEMENT_BUF, "verts"}, //input vertices
466          {0, /* null-terminating sentine */}},
467         bmo_rotate_exec,
468         0,
469 };
470
471 /*
472  * Translate
473  *
474  * Translate vertices by an offset.  Equivalent of the
475  * old translateflag function.
476  */
477 static BMOpDefine bmo_translate_def = {
478         "translate",
479         {{BMO_OP_SLOT_VEC, "vec"}, //translation offset
480          {BMO_OP_SLOT_ELEMENT_BUF, "verts"}, //input vertices
481          {0, /* null-terminating sentine */}},
482         bmo_translate_exec,
483         0,
484 };
485
486 /*
487  * Scale
488  *
489  * Scales vertices by an offset.
490  */
491 static BMOpDefine bmo_scale_def = {
492         "scale",
493         {{BMO_OP_SLOT_VEC, "vec"}, //scale factor
494          {BMO_OP_SLOT_ELEMENT_BUF, "verts"}, //input vertices
495          {0, /* null-terminating sentine */}},
496         bmo_scale_exec,
497         0,
498 };
499
500
501 /*
502  * Transform
503  *
504  * Transforms a set of vertices by a matrix.  Multiplies
505  * the vertex coordinates with the matrix.
506  */
507 static BMOpDefine bmo_transform_def = {
508         "transform",
509         {{BMO_OP_SLOT_MAT, "mat"}, //transform matrix
510          {BMO_OP_SLOT_ELEMENT_BUF, "verts"}, //input vertices
511          {0, /* null-terminating sentine */}},
512         bmo_transform_exec,
513         0,
514 };
515
516 /*
517  * Object Load BMesh
518  *
519  * Loads a bmesh into an object/mesh.  This is a "private"
520  * bmop.
521  */
522 static BMOpDefine bmo_object_load_bmesh_def = {
523         "object_load_bmesh",
524         {{BMO_OP_SLOT_PNT, "scene"},
525          {BMO_OP_SLOT_PNT, "object"},
526          {0, /* null-terminating sentine */}},
527         bmo_object_load_bmesh_exec,
528         0,
529 };
530
531
532 /*
533  * BMesh to Mesh
534  *
535  * Converts a bmesh to a Mesh.  This is reserved for exiting editmode.
536  */
537 static BMOpDefine bmo_bmesh_to_mesh_def = {
538         "bmesh_to_mesh",
539         {{BMO_OP_SLOT_PNT, "mesh"}, //pointer to a mesh structure to fill in
540          {BMO_OP_SLOT_PNT, "object"}, //pointer to an object structure
541          {BMO_OP_SLOT_BOOL, "notessellation"}, //don't calculate mfaces
542          {0, /* null-terminating sentine */}},
543         bmo_bmesh_to_mesh_exec,
544         0,
545 };
546
547 /*
548  * Mesh to BMesh
549  *
550  * Load the contents of a mesh into the bmesh.  this bmop is private, it's
551  * reserved exclusively for entering editmode.
552  */
553 static BMOpDefine bmo_mesh_to_bmesh_def = {
554         "mesh_to_bmesh",
555         {{BMO_OP_SLOT_PNT, "mesh"}, //pointer to a Mesh structure
556          {BMO_OP_SLOT_PNT, "object"}, //pointer to an Object structure
557          {BMO_OP_SLOT_BOOL, "set_shapekey"}, //load active shapekey coordinates into verts
558          {0, /* null-terminating sentine */}},
559         bmo_mesh_to_bmesh_exec,
560         0
561 };
562
563 /*
564  * Individual Face Extrude
565  *
566  * Extrudes faces individually.
567  */
568 static BMOpDefine bmo_extrude_indivface_def = {
569         "extrude_face_indiv",
570         {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, //input faces
571          {BMO_OP_SLOT_ELEMENT_BUF, "faceout"}, //output faces
572          {BMO_OP_SLOT_ELEMENT_BUF, "skirtout"}, //output skirt geometry, faces and edges
573          {0} /* null-terminating sentine */},
574         bmo_extrude_face_indiv_exec,
575         0
576 };
577
578 /*
579  * Extrude Only Edges
580  *
581  * Extrudes Edges into faces, note that this is very simple, there's no fancy
582  * winged extrusion.
583  */
584 static BMOpDefine bmo_extrude_edge_only_def = {
585         "extrude_edge_only",
586         {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, //input vertices
587          {BMO_OP_SLOT_ELEMENT_BUF, "geomout"}, //output geometry
588          {0} /* null-terminating sentine */},
589         bmo_extrude_edge_only_exec,
590         0
591 };
592
593 /*
594  * Individual Vertex Extrude
595  *
596  * Extrudes wire edges from vertices.
597  */
598 static BMOpDefine bmo_extrude_vert_indiv_def = {
599         "extrude_vert_indiv",
600         {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, //input vertices
601          {BMO_OP_SLOT_ELEMENT_BUF, "edgeout"}, //output wire edges
602          {BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, //output vertices
603          {0} /* null-terminating sentine */},
604         bmo_extrude_vert_indiv_exec,
605         0
606 };
607
608 static BMOpDefine bmo_connectverts_def = {
609         "connectverts",
610         {{BMO_OP_SLOT_ELEMENT_BUF, "verts"},
611          {BMO_OP_SLOT_ELEMENT_BUF, "edgeout"},
612          {0} /* null-terminating sentine */},
613         bmo_connectverts_exec,
614         BMO_OP_FLAG_UNTAN_MULTIRES
615 };
616
617 static BMOpDefine bmo_extrude_face_region_def = {
618         "extrude_face_region",
619         {{BMO_OP_SLOT_ELEMENT_BUF, "edgefacein"},
620          {BMO_OP_SLOT_MAPPING, "exclude"},
621          {BMO_OP_SLOT_BOOL, "alwayskeeporig"},
622          {BMO_OP_SLOT_ELEMENT_BUF, "geomout"},
623          {0} /* null-terminating sentine */},
624         bmo_extrude_face_region_exec,
625         0
626 };
627
628 static BMOpDefine bmo_dissolve_verts_def = {
629         "dissolve_verts",
630         {{BMO_OP_SLOT_ELEMENT_BUF, "verts"},
631          {0} /* null-terminating sentine */},
632         bmo_dissolve_verts_exec,
633         BMO_OP_FLAG_UNTAN_MULTIRES
634 };
635
636 static BMOpDefine bmo_dissolve_edges_def = {
637         "dissolve_edges",
638         {{BMO_OP_SLOT_ELEMENT_BUF, "edges"},
639          {BMO_OP_SLOT_ELEMENT_BUF, "regionout"},
640          {BMO_OP_SLOT_BOOL, "use_verts"}, // dissolve verts left between only 2 edges.
641          {0} /* null-terminating sentine */},
642         bmo_dissolve_edges_exec,
643         BMO_OP_FLAG_UNTAN_MULTIRES
644 };
645
646 static BMOpDefine bmo_dissolve_edge_loop_def = {
647         "dissolve_edge_loop",
648         {{BMO_OP_SLOT_ELEMENT_BUF, "edges"},
649          {BMO_OP_SLOT_ELEMENT_BUF, "regionout"},
650          {0} /* null-terminating sentine */},
651         bmo_dissolve_edgeloop_exec,
652         BMO_OP_FLAG_UNTAN_MULTIRES
653 };
654
655 static BMOpDefine bmo_dissolve_faces_def = {
656         "dissolve_faces",
657         {{BMO_OP_SLOT_ELEMENT_BUF, "faces"},
658          {BMO_OP_SLOT_ELEMENT_BUF, "regionout"},
659          {BMO_OP_SLOT_BOOL, "use_verts"}, // dissolve verts left between only 2 edges.
660          {0} /* null-terminating sentine */},
661         bmo_dissolve_faces_exec,
662         BMO_OP_FLAG_UNTAN_MULTIRES
663 };
664
665 static BMOpDefine bmo_dissolve_limit_def = {
666         "dissolve_limit",
667         {{BMO_OP_SLOT_FLT, "angle_limit"}, /* total rotation angle (degrees) */
668          {BMO_OP_SLOT_ELEMENT_BUF, "verts"},
669          {BMO_OP_SLOT_ELEMENT_BUF, "edges"},
670          {0} /* null-terminating sentine */},
671         bmo_dissolve_limit_exec,
672         BMO_OP_FLAG_UNTAN_MULTIRES
673 };
674
675 static BMOpDefine bmo_triangulate_def = {
676         "triangulate",
677         {{BMO_OP_SLOT_ELEMENT_BUF, "faces"},
678          {BMO_OP_SLOT_ELEMENT_BUF, "edgeout"},
679          {BMO_OP_SLOT_ELEMENT_BUF, "faceout"},
680          {BMO_OP_SLOT_MAPPING, "facemap"},
681          {BMO_OP_SLOT_BOOL, "use_beauty"},
682          {0} /* null-terminating sentine */},
683         bmo_triangulate_exec,
684         BMO_OP_FLAG_UNTAN_MULTIRES
685 };
686
687 static BMOpDefine bmo_esubd_def = {
688         "esubd",
689         {{BMO_OP_SLOT_ELEMENT_BUF, "edges"},
690          {BMO_OP_SLOT_INT, "numcuts"},
691          {BMO_OP_SLOT_FLT, "smooth"},
692          {BMO_OP_SLOT_FLT, "fractal"},
693          {BMO_OP_SLOT_INT, "beauty"},
694          {BMO_OP_SLOT_INT, "seed"},
695          {BMO_OP_SLOT_MAPPING, "custompatterns"},
696          {BMO_OP_SLOT_MAPPING, "edgepercents"},
697
698         /* these next three can have multiple types of elements in them */
699          {BMO_OP_SLOT_ELEMENT_BUF, "outinner"},
700          {BMO_OP_SLOT_ELEMENT_BUF, "outsplit"},
701          {BMO_OP_SLOT_ELEMENT_BUF, "geomout"}, /* contains all output geometr */
702
703          {BMO_OP_SLOT_INT,  "quadcornertype"}, //quad corner type, see bmesh_operators.h
704          {BMO_OP_SLOT_BOOL, "gridfill"}, //fill in fully-selected faces with a grid
705          {BMO_OP_SLOT_BOOL, "singleedge"}, //tessellate the case of one edge selected in a quad or triangle
706
707          {0} /* null-terminating sentine */,
708         },
709         bmo_esubd_exec,
710         BMO_OP_FLAG_UNTAN_MULTIRES
711 };
712
713 static BMOpDefine bmo_del_def = {
714         "del",
715         {{BMO_OP_SLOT_ELEMENT_BUF, "geom"},
716          {BMO_OP_SLOT_INT, "context"},
717          {0} /* null-terminating sentine */},
718         bmo_del_exec,
719         0
720 };
721
722 static BMOpDefine bmo_dupe_def = {
723         "dupe",
724         {{BMO_OP_SLOT_ELEMENT_BUF, "geom"},
725          {BMO_OP_SLOT_ELEMENT_BUF, "origout"},
726          {BMO_OP_SLOT_ELEMENT_BUF, "newout"},
727         /* facemap maps from source faces to dupe
728          * faces, and from dupe faces to source faces */
729          {BMO_OP_SLOT_MAPPING, "facemap"},
730          {BMO_OP_SLOT_MAPPING, "boundarymap"},
731          {BMO_OP_SLOT_MAPPING, "isovertmap"},
732          {BMO_OP_SLOT_PNT, "dest"}, /* destination bmesh, if NULL will use current on */
733          {0} /* null-terminating sentine */},
734         bmo_dupe_exec,
735         0
736 };
737
738 static BMOpDefine bmo_split_def = {
739         "split",
740         {{BMO_OP_SLOT_ELEMENT_BUF, "geom"},
741          {BMO_OP_SLOT_ELEMENT_BUF, "geomout"},
742          {BMO_OP_SLOT_MAPPING, "boundarymap"},
743          {BMO_OP_SLOT_MAPPING, "isovertmap"},
744          {BMO_OP_SLOT_PNT, "dest"}, /* destination bmesh, if NULL will use current on */
745          {BMO_OP_SLOT_BOOL, "use_only_faces"}, /* when enabled. don't duplicate loose verts/edges */
746          {0} /* null-terminating sentine */},
747         bmo_split_exec,
748         0
749 };
750
751 /*
752  * Spin
753  *
754  * Extrude or duplicate geometry a number of times,
755  * rotating and possibly translating after each step
756  */
757 static BMOpDefine bmo_spin_def = {
758         "spin",
759         {{BMO_OP_SLOT_ELEMENT_BUF, "geom"},
760          {BMO_OP_SLOT_ELEMENT_BUF, "lastout"}, /* result of last step */
761          {BMO_OP_SLOT_VEC, "cent"}, /* rotation center */
762          {BMO_OP_SLOT_VEC, "axis"}, /* rotation axis */
763          {BMO_OP_SLOT_VEC, "dvec"}, /* translation delta per step */
764          {BMO_OP_SLOT_FLT, "ang"}, /* total rotation angle (degrees) */
765          {BMO_OP_SLOT_INT, "steps"}, /* number of steps */
766          {BMO_OP_SLOT_BOOL, "do_dupli"}, /* duplicate or extrude? */
767          {0} /* null-terminating sentine */},
768         bmo_spin_exec,
769         0
770 };
771
772
773 /*
774  * Similar faces search
775  *
776  * Find similar faces (area/material/perimeter, ...).
777  */
778 static BMOpDefine bmo_similarfaces_def = {
779         "similarfaces",
780         {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
781          {BMO_OP_SLOT_ELEMENT_BUF, "faceout"}, /* output faces */
782          {BMO_OP_SLOT_INT, "type"},                     /* type of selection */
783          {BMO_OP_SLOT_FLT, "thresh"},           /* threshold of selection */
784          {0} /* null-terminating sentine */},
785         bmo_similarfaces_exec,
786         0
787 };
788
789 /*
790  * Similar edges search
791  *
792  *  Find similar edges (length, direction, edge, seam, ...).
793  */
794 static BMOpDefine bmo_similaredges_def = {
795         "similaredges",
796         {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edges */
797          {BMO_OP_SLOT_ELEMENT_BUF, "edgeout"}, /* output edges */
798          {BMO_OP_SLOT_INT, "type"},                     /* type of selection */
799          {BMO_OP_SLOT_FLT, "thresh"},           /* threshold of selection */
800          {0} /* null-terminating sentine */},
801         bmo_similaredges_exec,
802         0
803 };
804
805 /*
806  * Similar vertices search
807  *
808  * Find similar vertices (normal, face, vertex group, ...).
809  */
810 static BMOpDefine bmo_similarverts_def = {
811         "similarverts",
812         {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */
813          {BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, /* output vertices */
814          {BMO_OP_SLOT_INT, "type"},                     /* type of selection */
815          {BMO_OP_SLOT_FLT, "thresh"},           /* threshold of selection */
816          {0} /* null-terminating sentine */},
817         bmo_similarverts_exec,
818         0
819 };
820
821 /*
822  * uv rotation
823  * cycle the uvs
824  */
825 static BMOpDefine bmo_face_rotateuvs_def = {
826         "face_rotateuvs",
827         {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
828          {BMO_OP_SLOT_INT, "dir"},                      /* direction */
829          {0} /* null-terminating sentine */},
830         bmo_face_rotateuvs_exec,
831         0
832 };
833
834 /*
835  * uv reverse
836  * reverse the uvs
837  */
838 static BMOpDefine bmo_face_reverseuvs_def = {
839         "face_reverseuvs",
840         {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
841          {0} /* null-terminating sentine */},
842         bmo_face_reverseuvs_exec,
843         0
844 };
845
846 /*
847  * color rotation
848  * cycle the colors
849  */
850 static BMOpDefine bmo_face_rotatecolors_def = {
851         "face_rotatecolors",
852         {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
853          {BMO_OP_SLOT_INT, "dir"},                      /* direction */
854          {0} /* null-terminating sentine */},
855         bmo_rotatecolors_exec,
856         0
857 };
858
859 /*
860  * color reverse
861  * reverse the colors
862  */
863 static BMOpDefine bmo_face_reversecolors_def = {
864         "face_reversecolors",
865         {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
866          {0} /* null-terminating sentine */},
867         bmo_face_reversecolors_exec,
868         0
869 };
870
871 /*
872  * Similar vertices search
873  *
874  * Find similar vertices (normal, face, vertex group, ...).
875  */
876 static BMOpDefine bmo_vertexshortestpath_def = {
877         "vertexshortestpath",
878         {{BMO_OP_SLOT_ELEMENT_BUF, "startv"}, /* start vertex */
879          {BMO_OP_SLOT_ELEMENT_BUF, "endv"}, /* end vertex */
880          {BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, /* output vertices */
881          {BMO_OP_SLOT_INT, "type"},                     /* type of selection */
882          {0} /* null-terminating sentine */},
883         bmo_vertexshortestpath_exec,
884         0
885 };
886
887 /*
888  * Edge Split
889  *
890  * Disconnects faces along input edges.
891  */
892 static BMOpDefine bmo_edgesplit_def = {
893         "edgesplit",
894         {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edges */
895          {BMO_OP_SLOT_ELEMENT_BUF, "edgeout"}, /* old output disconnected edges */
896          /* needed for vertex rip so we can rip only half an edge at a boundary wich would otherwise split off */
897          {BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* optional tag verts, use to have greater control of splits */
898          {BMO_OP_SLOT_BOOL,        "use_verts"}, /* use 'verts' for splitting, else just find verts to split from edges */
899          {0} /* null-terminating sentine */},
900         bmo_edgesplit_exec,
901         BMO_OP_FLAG_UNTAN_MULTIRES
902 };
903
904 /*
905  * Create Grid
906  *
907  * Creates a grid with a variable number of subdivisions
908  */
909 static BMOpDefine bmo_create_grid_def = {
910         "create_grid",
911         {{BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, //output verts
912          {BMO_OP_SLOT_INT,         "xsegments"}, //number of x segments
913          {BMO_OP_SLOT_INT,         "ysegments"}, //number of y segments
914          {BMO_OP_SLOT_FLT,         "size"}, //size of the grid
915          {BMO_OP_SLOT_MAT,         "mat"}, //matrix to multiply the new geometry with
916          {0, /* null-terminating sentine */}},
917         bmo_create_grid_exec,
918         0,
919 };
920
921 /*
922  * Create UV Sphere
923  *
924  * Creates a grid with a variable number of subdivisions
925  */
926 static BMOpDefine bmo_create_uvsphere_def = {
927         "create_uvsphere",
928         {{BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, //output verts
929          {BMO_OP_SLOT_INT,         "segments"}, //number of u segments
930          {BMO_OP_SLOT_INT,         "revolutions"}, //number of v segment
931          {BMO_OP_SLOT_FLT,         "diameter"}, //diameter
932          {BMO_OP_SLOT_MAT,         "mat"}, //matrix to multiply the new geometry with--
933          {0, /* null-terminating sentine */}},
934         bmo_create_uvsphere_exec,
935         0,
936 };
937
938 /*
939  * Create Ico Sphere
940  *
941  * Creates a grid with a variable number of subdivisions
942  */
943 static BMOpDefine bmo_create_icosphere_def = {
944         "create_icosphere",
945         {{BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, //output verts
946          {BMO_OP_SLOT_INT,         "subdivisions"}, //how many times to recursively subdivide the sphere
947          {BMO_OP_SLOT_FLT,         "diameter"}, //diameter
948          {BMO_OP_SLOT_MAT,         "mat"}, //matrix to multiply the new geometry with
949          {0, /* null-terminating sentine */}},
950         bmo_create_icosphere_exec,
951         0,
952 };
953
954 /*
955  * Create Suzanne
956  *
957  * Creates a monkey.  Be wary.
958  */
959 static BMOpDefine bmo_create_monkey_def = {
960         "create_monkey",
961         {{BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, //output verts
962          {BMO_OP_SLOT_MAT, "mat"}, //matrix to multiply the new geometry with--
963          {0, /* null-terminating sentine */}},
964         bmo_create_monkey_exec,
965         0,
966 };
967
968 /*
969  * Create Cone
970  *
971  * Creates a cone with variable depth at both ends
972  */
973 static BMOpDefine bmo_create_cone_def = {
974         "create_cone",
975         {{BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, //output verts
976          {BMO_OP_SLOT_BOOL, "cap_ends"}, //wheter or not to fill in the ends with faces
977          {BMO_OP_SLOT_BOOL, "cap_tris"}, //fill ends with triangles instead of ngons
978          {BMO_OP_SLOT_INT, "segments"},
979          {BMO_OP_SLOT_FLT, "diameter1"}, //diameter of one end
980          {BMO_OP_SLOT_FLT, "diameter2"}, //diameter of the opposite
981          {BMO_OP_SLOT_FLT, "depth"}, //distance between ends
982          {BMO_OP_SLOT_MAT, "mat"}, //matrix to multiply the new geometry with--
983          {0, /* null-terminating sentine */}},
984         bmo_create_cone_exec,
985         0,
986 };
987
988 /*
989  * Creates a circle
990  */
991 static BMOpDefine bmo_create_circle_def = {
992         "create_circle",
993         {{BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, //output verts
994          {BMO_OP_SLOT_BOOL, "cap_ends"}, //wheter or not to fill in the ends with faces
995          {BMO_OP_SLOT_BOOL, "cap_tris"}, //fill ends with triangles instead of ngons
996          {BMO_OP_SLOT_INT, "segments"},
997          {BMO_OP_SLOT_FLT, "diameter"}, //diameter of one end
998          {BMO_OP_SLOT_MAT, "mat"}, //matrix to multiply the new geometry with--
999          {0, /* null-terminating sentine */}},
1000         bmo_create_circle_exec,
1001         0,
1002 };
1003
1004 /*
1005  * Create Cone
1006  *
1007  * Creates a cone with variable depth at both ends
1008  */
1009 static BMOpDefine bmo_create_cube_def = {
1010         "create_cube",
1011         {{BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, //output verts
1012          {BMO_OP_SLOT_FLT, "size"}, //size of the cube
1013          {BMO_OP_SLOT_MAT, "mat"}, //matrix to multiply the new geometry with--
1014          {0, /* null-terminating sentine */}},
1015         bmo_create_cube_exec,
1016         0,
1017 };
1018
1019 /*
1020  * Bevel
1021  *
1022  * Bevels edges and vertices
1023  */
1024 static BMOpDefine bmo_bevel_def = {
1025         "bevel",
1026         {{BMO_OP_SLOT_ELEMENT_BUF, "geom"}, /* input edges and vertices */
1027          {BMO_OP_SLOT_ELEMENT_BUF, "face_spans"}, /* new geometry */
1028          {BMO_OP_SLOT_ELEMENT_BUF, "face_holes"}, /* new geometry */
1029          {BMO_OP_SLOT_BOOL, "use_lengths"}, /* grab edge lengths from a PROP_FLT customdata laye */
1030          {BMO_OP_SLOT_BOOL, "use_even"}, /* corner vert placement: use shell/angle calculations  */
1031          {BMO_OP_SLOT_BOOL, "use_dist"}, /* corner vert placement: evaluate percent as a distance,
1032                                           * modifier uses this. We could do this as another float setting */
1033          {BMO_OP_SLOT_INT, "lengthlayer"}, /* which PROP_FLT layer to us */
1034          {BMO_OP_SLOT_FLT, "percent"}, /* percentage to expand bevelled edge */
1035          {0} /* null-terminating sentine */},
1036         bmo_bevel_exec,
1037         BMO_OP_FLAG_UNTAN_MULTIRES
1038 };
1039
1040 /*
1041  * Beautify Fill
1042  *
1043  * Makes triangle a bit nicer
1044  */
1045 static BMOpDefine bmo_beautify_fill_def = {
1046         "beautify_fill",
1047         {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
1048          {BMO_OP_SLOT_ELEMENT_BUF, "constrain_edges"}, /* edges that can't be flipped */
1049          {BMO_OP_SLOT_ELEMENT_BUF, "geomout"}, /* new flipped faces and edges */
1050          {0} /* null-terminating sentine */},
1051         bmo_beautify_fill_exec,
1052         BMO_OP_FLAG_UNTAN_MULTIRES
1053 };
1054
1055 /*
1056  * Triangle Fill
1057  *
1058  * Fill edges with triangles
1059  */
1060 static BMOpDefine bmo_triangle_fill_def = {
1061         "triangle_fill",
1062         {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edges */
1063          {BMO_OP_SLOT_ELEMENT_BUF, "geomout"}, /* new faces and edges */
1064          {0} /* null-terminating sentine */},
1065         bmo_triangle_fill_exec,
1066         BMO_OP_FLAG_UNTAN_MULTIRES
1067 };
1068
1069 /*
1070  * Solidify
1071  *
1072  * Turns a mesh into a shell with thickness
1073  */
1074 static BMOpDefine bmo_solidify_def = {
1075         "solidify",
1076         {{BMO_OP_SLOT_ELEMENT_BUF, "geom"},
1077          {BMO_OP_SLOT_FLT, "thickness"},
1078          {BMO_OP_SLOT_ELEMENT_BUF, "geomout"},
1079          {0}},
1080         bmo_solidify_face_region_exec,
1081         0
1082 };
1083
1084 /*
1085  * Face Inset
1086  *
1087  * Extrudes faces individually.
1088  */
1089 static BMOpDefine bmo_inset_def = {
1090         "inset",
1091         {{BMO_OP_SLOT_ELEMENT_BUF, "faces"},   /* input faces */
1092          {BMO_OP_SLOT_ELEMENT_BUF, "faceout"}, /* output faces */
1093          {BMO_OP_SLOT_BOOL, "use_boundary"},
1094          {BMO_OP_SLOT_BOOL, "use_even_offset"},
1095          {BMO_OP_SLOT_BOOL, "use_relative_offset"},
1096          {BMO_OP_SLOT_FLT, "thickness"},
1097          {BMO_OP_SLOT_BOOL, "use_outset"},
1098          {0} /* null-terminating sentine */},
1099         bmo_inset_exec,
1100         0
1101 };
1102
1103 BMOpDefine *opdefines[] = {
1104         &bmo_split_def,
1105         &bmo_spin_def,
1106         &bmo_dupe_def,
1107         &bmo_del_def,
1108         &bmo_esubd_def,
1109         &bmo_triangulate_def,
1110         &bmo_dissolve_faces_def,
1111         &bmo_dissolve_edges_def,
1112         &bmo_dissolve_edge_loop_def,
1113         &bmo_dissolve_verts_def,
1114         &bmo_dissolve_limit_def,
1115         &bmo_extrude_face_region_def,
1116         &bmo_connectverts_def,
1117         &bmo_extrude_vert_indiv_def,
1118         &bmo_mesh_to_bmesh_def,
1119         &bmo_object_load_bmesh_def,
1120         &bmo_transform_def,
1121         &bmo_translate_def,
1122         &bmo_rotate_def,
1123         &bmo_edgenet_fill_def,
1124         &bmo_contextual_create_def,
1125         &bmo_makevert_def,
1126         &bmo_weldverts_def,
1127         &bmo_removedoubles_def,
1128         &bmo_finddoubles_def,
1129         &bmo_mirror_def,
1130         &bmo_edgebisect_def,
1131         &bmo_reversefaces_def,
1132         &bmo_edgerotate_def,
1133         &bmo_regionextend_def,
1134         &bmo_righthandfaces_def,
1135         &bmo_vertexsmooth_def,
1136         &bmo_extrude_edge_only_def,
1137         &bmo_extrude_indivface_def,
1138         &bmo_collapse_uvs_def,
1139         &bmo_pointmerge_def,
1140         &bmo_collapse_def,
1141         &bmo_similarfaces_def,
1142         &bmo_similaredges_def,
1143         &bmo_similarverts_def,
1144         &bmo_pointmerge_facedata_def,
1145         &bmo_vert_average_facedata_def,
1146         &bmo_face_rotateuvs_def,
1147         &bmo_bmesh_to_mesh_def,
1148         &bmo_face_reverseuvs_def,
1149         &bmo_edgenet_prepare_def,
1150         &bmo_face_rotatecolors_def,
1151         &bmo_face_reversecolors_def,
1152         &bmo_vertexshortestpath_def,
1153         &bmo_scale_def,
1154         &bmo_edgesplit_def,
1155         &bmo_automerge_def,
1156         &bmo_create_uvsphere_def,
1157         &bmo_create_grid_def,
1158         &bmo_create_icosphere_def,
1159         &bmo_create_monkey_def,
1160         &bmo_create_cube_def,
1161         &bmo_create_circle_def,
1162         &bmo_create_cone_def,
1163         &bmo_join_triangles_def,
1164         &bmo_bevel_def,
1165         &bmo_beautify_fill_def,
1166         &bmo_triangle_fill_def,
1167         &bmo_bridge_loops_def,
1168         &bmo_solidify_def,
1169         &bmo_inset_def,
1170 };
1171
1172 int bmesh_total_ops = (sizeof(opdefines) / sizeof(void *));