copying bmesh dir on its own from bmesh branch
[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 "bmesh.h"
58 #include "bmesh_private.h"
59
60 /* ok, I'm going to write a little docgen script. so all
61  * bmop comments must conform to the following template/rules:
62  *
63  * template (py quotes used because nested comments don't work
64  * on all C compilers):
65  *
66  * """
67  * Region Extend.
68  *
69  * paragraph1, Extends bleh bleh bleh.
70  * Bleh Bleh bleh.
71  *
72  * Another paragraph.
73  *
74  * Another paragraph.
75  * """
76  *
77  * so the first line is the "title" of the bmop.
78  * subsequent line blocks seperated by blank lines
79  * are paragraphs.  individual descriptions of slots
80  * would be extracted from comments
81  * next to them, e.g.
82  *
83  * {BMO_OP_SLOT_ELEMENT_BUF, "geomout"}, //output slot, boundary region
84  *
85  * the doc generator would automatically detect the presence of "output slot"
86  * and flag the slot as an output.  the same happens for "input slot".  also
87  * note that "edges", "faces", "verts", "loops", and "geometry" are valid
88  * substitutions for "slot".
89  *
90  * note that slots default to being input slots.
91  */
92
93 /*
94  * Vertex Smooth
95  *
96  * Smoothes vertices by using a basic vertex averaging scheme.
97  */
98 static BMOpDefine def_vertexsmooth = {
99         "vertexsmooth",
100         {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, //input vertices
101          {BMO_OP_SLOT_INT, "mirror_clip_x"}, //set vertices close to the x axis before the operation to 0
102          {BMO_OP_SLOT_INT, "mirror_clip_y"}, //set vertices close to the y axis before the operation to 0
103          {BMO_OP_SLOT_INT, "mirror_clip_z"}, //set vertices close to the z axis before the operation to 0
104          {BMO_OP_SLOT_FLT, "clipdist"}, //clipping threshod for the above three slots
105         {0} /* null-terminating sentine */,
106         },
107         bmesh_vertexsmooth_exec,
108         0
109 };
110
111 /*
112  * Right-Hand Faces
113  *
114  * Computes an "outside" normal for the specified input faces.
115  */
116
117 static BMOpDefine def_righthandfaces = {
118         "righthandfaces",
119         {{BMO_OP_SLOT_ELEMENT_BUF, "faces"},
120          {BMO_OP_SLOT_INT, "doflip"}, //internal flag, used by bmesh_rationalize_normals
121          {0} /* null-terminating sentine */,
122         },
123         bmesh_righthandfaces_exec,
124         BMO_OP_FLAG_UNTAN_MULTIRES,
125 };
126
127 /*
128  * Region Extend
129  *
130  * used to implement the select more/less tools.
131  * this puts some geometry surrounding regions of
132  * geometry in geom into geomout.
133  *
134  * if usefaces is 0 then geomout spits out verts and edges,
135  * otherwise it spits out faces.
136  */
137 static BMOpDefine def_regionextend = {
138         "regionextend",
139         {{BMO_OP_SLOT_ELEMENT_BUF, "geom"}, //input geometry
140          {BMO_OP_SLOT_ELEMENT_BUF, "geomout"}, //output slot, computed boundary geometry.
141          {BMO_OP_SLOT_INT, "constrict"}, //find boundary inside the regions, not outside.
142          {BMO_OP_SLOT_INT, "usefaces"}, //extend from faces instead of edges
143          {0} /* null-terminating sentine */,
144         },
145         bmesh_regionextend_exec,
146         0
147 };
148
149 /*
150  * Edge Rotate
151  *
152  * Rotates edges topologically.  Also known as "spin edge" to some people.
153  * Simple example: [/] becomes [|] then [\].
154  */
155 static BMOpDefine def_edgerotate = {
156         "edgerotate",
157         {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, //input edges
158          {BMO_OP_SLOT_ELEMENT_BUF, "edgeout"}, //newly spun edges
159          {BMO_OP_SLOT_INT, "ccw"}, //rotate edge counter-clockwise if true, othewise clockwise
160          {0} /* null-terminating sentine */,
161         },
162         bmesh_edgerotate_exec,
163         BMO_OP_FLAG_UNTAN_MULTIRES
164 };
165
166 /*
167  * Reverse Faces
168  *
169  * Reverses the winding (vertex order) of faces.  This has the effect of
170  * flipping the normal.
171  */
172 static BMOpDefine def_reversefaces = {
173         "reversefaces",
174         {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, //input faces
175          {0} /* null-terminating sentine */,
176         },
177         bmesh_reversefaces_exec,
178         BMO_OP_FLAG_UNTAN_MULTIRES,
179 };
180
181 /*
182  * Edge Bisect
183  *
184  * Splits input edges (but doesn't do anything else).
185  * This creates a 2-valence vert.
186  */
187 static BMOpDefine def_edgebisect = {
188         "edgebisect",
189         {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, //input edges
190          {BMO_OP_SLOT_INT, "numcuts"}, //number of cuts
191          {BMO_OP_SLOT_ELEMENT_BUF, "outsplit"}, //newly created vertices and edges
192          {0} /* null-terminating sentine */,
193         },
194         esplit_exec,
195         BMO_OP_FLAG_UNTAN_MULTIRES
196 };
197
198 /*
199  * Mirror
200  *
201  * Mirrors geometry along an axis.  The resulting geometry is welded on using
202  * mergedist.  Pairs of original/mirrored vertices are welded using the mergedist
203  * parameter (which defines the minimum distance for welding to happen).
204  */
205
206 static BMOpDefine def_mirror = {
207         "mirror",
208         {{BMO_OP_SLOT_ELEMENT_BUF, "geom"}, //input geometry
209          {BMO_OP_SLOT_MAT, "mat"}, //matrix defining the mirror transformation
210          {BMO_OP_SLOT_FLT, "mergedist"}, //maximum distance for merging.  does no merging if 0.
211          {BMO_OP_SLOT_ELEMENT_BUF, "newout"}, //output geometry, mirrored
212          {BMO_OP_SLOT_INT,         "axis"}, //the axis to use, 0, 1, or 2 for x, y, z
213          {BMO_OP_SLOT_INT,         "mirror_u"}, //mirror UVs across the u axis
214          {BMO_OP_SLOT_INT,         "mirror_v"}, //mirror UVs across the v axis
215          {0, /* null-terminating sentine */}},
216         bmesh_mirror_exec,
217         0,
218 };
219
220 /*
221  * Find Doubles
222  *
223  * Takes input verts and find vertices they should weld to.  Outputs a
224  * mapping slot suitable for use with the weld verts bmop.
225  */
226 static BMOpDefine def_finddoubles = {
227         "finddoubles",
228         {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, //input vertices
229          {BMO_OP_SLOT_ELEMENT_BUF, "keepverts"}, //list of verts to keep
230          {BMO_OP_SLOT_FLT,         "dist"}, //minimum distance
231          {BMO_OP_SLOT_MAPPING, "targetmapout"},
232          {0, /* null-terminating sentine */}},
233         bmesh_finddoubles_exec,
234         0,
235 };
236
237 /*
238  * Remove Doubles
239  *
240  * Finds groups of vertices closer then dist and merges them together,
241  * using the weld verts bmop.
242  */
243 static BMOpDefine def_removedoubles = {
244         "removedoubles",
245         {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, //input verts
246          {BMO_OP_SLOT_FLT,         "dist"}, //minimum distance
247          {0, /* null-terminating sentine */}},
248         bmesh_removedoubles_exec,
249         BMO_OP_FLAG_UNTAN_MULTIRES,
250 };
251
252 /*
253  * Auto Merge
254  *
255  * Finds groups of vertices closer then dist and merges them together,
256  * using the weld verts bmop.  The merges must go from a vert not in
257  * verts to one in verts.
258  */
259 static BMOpDefine def_automerge = {
260         "automerge",
261         {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, //input verts
262          {BMO_OP_SLOT_FLT,         "dist"}, //minimum distance
263          {0, /* null-terminating sentine */}},
264         bmesh_automerge_exec,
265         BMO_OP_FLAG_UNTAN_MULTIRES,
266 };
267
268 /*
269  * Collapse Connected
270  *
271  * Collapses connected vertices
272  */
273 static BMOpDefine def_collapse = {
274         "collapse",
275         {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edge */
276          {0, /* null-terminating sentine */}},
277         bmesh_collapse_exec,
278         BMO_OP_FLAG_UNTAN_MULTIRES,
279 };
280
281
282 /*
283  * Facedata point Merge
284  *
285  * Merge uv/vcols at a specific vertex.
286  */
287 static BMOpDefine def_pointmerge_facedata = {
288         "pointmerge_facedata",
289         {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertice */
290          {BMO_OP_SLOT_ELEMENT_BUF, "snapv"}, /* snap verte */
291          {0, /* null-terminating sentine */}},
292         bmesh_pointmerge_facedata_exec,
293         0,
294 };
295
296 /*
297  * Average Vertices Facevert Data
298  *
299  * Merge uv/vcols associated with the input vertices at
300  * the bounding box center. (I know, it's not averaging but
301  * the vert_snap_to_bb_center is just too long).
302  */
303 static BMOpDefine def_vert_average_facedata = {
304         "vert_average_facedata",
305         {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertice */
306          {0, /* null-terminating sentine */}},
307         bmesh_vert_average_facedata_exec,
308         0,
309 };
310
311 /*
312  * Point Merge
313  *
314  * Merge verts together at a point.
315  */
316 static BMOpDefine def_pointmerge = {
317         "pointmerge",
318         {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertice */
319          {BMO_OP_SLOT_VEC,         "mergeco"},
320          {0, /* null-terminating sentine */}},
321         bmesh_pointmerge_exec,
322         BMO_OP_FLAG_UNTAN_MULTIRES,
323 };
324
325 /*
326  * Collapse Connected UVs
327  *
328  * Collapses connected UV vertices.
329  */
330 static BMOpDefine def_collapse_uvs = {
331         "collapse_uvs",
332         {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edge */
333          {0, /* null-terminating sentine */}},
334         bmesh_collapsecon_exec,
335         0,
336 };
337
338 /*
339  * Weld Verts
340  *
341  * Welds verts together (kindof like remove doubles, merge, etc, all of which
342  * use or will use this bmop).  You pass in mappings from vertices to the vertices
343  * they weld with.
344  */
345 static BMOpDefine def_weldverts = {
346         "weldverts",
347         {{BMO_OP_SLOT_MAPPING, "targetmap"}, /* maps welded vertices to verts they should weld to */
348          {0, /* null-terminating sentine */}},
349         bmesh_weldverts_exec,
350         BMO_OP_FLAG_UNTAN_MULTIRES,
351 };
352
353 /*
354  * Make Vertex
355  *
356  * Creates a single vertex; this bmop was necassary
357  * for click-create-vertex.
358  */
359 static BMOpDefine def_makevert = {
360         "makevert",
361         {{BMO_OP_SLOT_VEC, "co"}, //the coordinate of the new vert
362          {BMO_OP_SLOT_ELEMENT_BUF, "newvertout"}, //the new vert
363          {0, /* null-terminating sentine */}},
364         bmesh_makevert_exec,
365         0,
366 };
367
368 /*
369  * Join Triangles
370  *
371  * Tries to intelligently join triangles according
372  * to various settings and stuff.
373  */
374 static BMOpDefine def_join_triangles = {
375         "join_triangles",
376         {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, //input geometry.
377          {BMO_OP_SLOT_ELEMENT_BUF, "faceout"}, //joined faces
378          {BMO_OP_SLOT_INT, "compare_sharp"},
379          {BMO_OP_SLOT_INT, "compare_uvs"},
380          {BMO_OP_SLOT_INT, "compare_vcols"},
381          {BMO_OP_SLOT_INT, "compare_materials"},
382          {BMO_OP_SLOT_FLT, "limit"},
383          {0, /* null-terminating sentine */}},
384         bmesh_jointriangles_exec,
385         BMO_OP_FLAG_UNTAN_MULTIRES,
386 };
387
388 /*
389  * Contextual Create
390  *
391  * This is basically fkey, it creates
392  * new faces from vertices, makes stuff from edge nets,
393  * makes wire edges, etc.  It also dissolves
394  * faces.
395  *
396  * Three verts become a triangle, four become a quad.  Two
397  * become a wire edge.
398  */
399 static BMOpDefine def_contextual_create = {
400         "contextual_create",
401         {{BMO_OP_SLOT_ELEMENT_BUF, "geom"}, //input geometry.
402          {BMO_OP_SLOT_ELEMENT_BUF, "faceout"}, //newly-made face(s)
403          {0, /* null-terminating sentine */}},
404         bmesh_contextual_create_exec,
405         BMO_OP_FLAG_UNTAN_MULTIRES,
406 };
407
408 /*
409  * Bridge edge loops with faces
410  */
411 static BMOpDefine def_bridge_loops = {
412         "bridge_loops",
413         {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edge */
414          {BMO_OP_SLOT_ELEMENT_BUF, "faceout"}, /* new face */
415          {0, /* null-terminating sentine */}},
416         bmesh_bridge_loops_exec,
417         0,
418 };
419
420 static BMOpDefine def_edgenet_fill = {
421         "edgenet_fill",
422         {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edge */
423          {BMO_OP_SLOT_MAPPING,     "restrict"}, /* restricts edges to groups.  maps edges to integer */
424          {BMO_OP_SLOT_INT,         "use_restrict"},
425          {BMO_OP_SLOT_ELEMENT_BUF, "excludefaces"}, /* list of faces to ignore for manifold check */
426          {BMO_OP_SLOT_MAPPING,     "faceout_groupmap"}, /* maps new faces to the group numbers they came fro */
427          {BMO_OP_SLOT_ELEMENT_BUF, "faceout"}, /* new face */
428          {0, /* null-terminating sentine */}},
429         bmesh_edgenet_fill_exec,
430         0,
431 };
432
433 /*
434  * Edgenet Prepare
435  *
436  * Identifies several useful edge loop cases and modifies them so
437  * they'll become a face when edgenet_fill is called.  The cases covered are:
438  *
439  * - One single loop; an edge is added to connect the ends
440  * - Two loops; two edges are added to connect the endpoints (based on the
441  *   shortest distance between each endpont).
442  */
443 static BMOpDefine def_edgenet_prepare = {
444         "edgenet_prepare",
445         {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, //input edges
446          {BMO_OP_SLOT_ELEMENT_BUF, "edgeout"}, //new edges
447          {0, /* null-terminating sentine */}},
448         bmesh_edgenet_prepare,
449         0,
450 };
451
452 /*
453  * Rotate
454  *
455  * Rotate vertices around a center, using a 3x3 rotation
456  * matrix.  Equivilent of the old rotateflag function.
457  */
458 static BMOpDefine def_rotate = {
459         "rotate",
460         {{BMO_OP_SLOT_VEC, "cent"}, //center of rotation
461          {BMO_OP_SLOT_MAT, "mat"}, //matrix defining rotation
462          {BMO_OP_SLOT_ELEMENT_BUF, "verts"}, //input vertices
463          {0, /* null-terminating sentine */}},
464         bmesh_rotate_exec,
465         0,
466 };
467
468 /*
469  * Translate
470  *
471  * Translate vertices by an offset.  Equivelent of the
472  * old translateflag function.
473  */
474 static BMOpDefine def_translate = {
475         "translate",
476         {{BMO_OP_SLOT_VEC, "vec"}, //translation offset
477          {BMO_OP_SLOT_ELEMENT_BUF, "verts"}, //input vertices
478          {0, /* null-terminating sentine */}},
479         bmesh_translate_exec,
480         0,
481 };
482
483 /*
484  * Scale
485  *
486  * Scales vertices by an offset.
487  */
488 static BMOpDefine def_scale = {
489         "scale",
490         {{BMO_OP_SLOT_VEC, "vec"}, //scale factor
491          {BMO_OP_SLOT_ELEMENT_BUF, "verts"}, //input vertices
492          {0, /* null-terminating sentine */}},
493         bmesh_scale_exec,
494         0,
495 };
496
497
498 /*
499  * Transform
500  *
501  * Transforms a set of vertices by a matrix.  Multiplies
502  * the vertex coordinates with the matrix.
503  */
504 static BMOpDefine def_transform = {
505         "transform",
506         {{BMO_OP_SLOT_MAT, "mat"}, //transform matrix
507          {BMO_OP_SLOT_ELEMENT_BUF, "verts"}, //input vertices
508          {0, /* null-terminating sentine */}},
509         bmesh_transform_exec,
510         0,
511 };
512
513 /*
514  * Object Load BMesh
515  *
516  * Loads a bmesh into an object/mesh.  This is a "private"
517  * bmop.
518  */
519 static BMOpDefine def_object_load_bmesh = {
520         "object_load_bmesh",
521         {{BMO_OP_SLOT_PNT, "scene"},
522          {BMO_OP_SLOT_PNT, "object"},
523          {0, /* null-terminating sentine */}},
524         object_load_bmesh_exec,
525         0,
526 };
527
528
529 /*
530  * BMesh to Mesh
531  *
532  * Converts a bmesh to a Mesh.  This is reserved for exiting editmode.
533  */
534 static BMOpDefine def_bmesh_to_mesh = {
535         "bmesh_to_mesh",
536         {{BMO_OP_SLOT_PNT, "mesh"}, //pointer to a mesh structure to fill in
537          {BMO_OP_SLOT_PNT, "object"}, //pointer to an object structure
538          {BMO_OP_SLOT_INT, "notesselation"}, //don't calculate mfaces
539          {0, /* null-terminating sentine */}},
540         bmesh_to_mesh_exec,
541         0,
542 };
543
544 /*
545  * Mesh to BMesh
546  *
547  * Load the contents of a mesh into the bmesh.  this bmop is private, it's
548  * reserved exclusively for entering editmode.
549  */
550 static BMOpDefine def_mesh_to_bmesh = {
551         "mesh_to_bmesh",
552         {{BMO_OP_SLOT_PNT, "mesh"}, //pointer to a Mesh structure
553          {BMO_OP_SLOT_PNT, "object"}, //pointer to an Object structure
554          {BMO_OP_SLOT_INT, "set_shapekey"}, //load active shapekey coordinates into verts
555          {0, /* null-terminating sentine */}},
556         mesh_to_bmesh_exec,
557         0
558 };
559
560 /*
561  * Individual Face Extrude
562  *
563  * Extrudes faces individually.
564  */
565 static BMOpDefine def_extrude_indivface = {
566         "extrude_face_indiv",
567         {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, //input faces
568          {BMO_OP_SLOT_ELEMENT_BUF, "faceout"}, //output faces
569          {BMO_OP_SLOT_ELEMENT_BUF, "skirtout"}, //output skirt geometry, faces and edges
570          {0} /* null-terminating sentine */},
571         bmesh_extrude_face_indiv_exec,
572         0
573 };
574
575 /*
576  * Extrude Only Edges
577  *
578  * Extrudes Edges into faces, note that this is very simple, there's no fancy
579  * winged extrusion.
580  */
581 static BMOpDefine def_extrude_onlyedge = {
582         "extrude_edge_only",
583         {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, //input vertices
584          {BMO_OP_SLOT_ELEMENT_BUF, "geomout"}, //output geometry
585          {0} /* null-terminating sentine */},
586         bmesh_extrude_onlyedge_exec,
587         0
588 };
589
590 /*
591  * Individual Vertex Extrude
592  *
593  * Extrudes wire edges from vertices.
594  */
595 static BMOpDefine def_extrudeverts_indiv = {
596         "extrude_vert_indiv",
597         {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, //input vertices
598          {BMO_OP_SLOT_ELEMENT_BUF, "edgeout"}, //output wire edges
599          {BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, //output vertices
600          {0} /* null-terminating sentine */},
601         extrude_vert_indiv_exec,
602         0
603 };
604
605 static BMOpDefine def_connectverts = {
606         "connectverts",
607         {{BMO_OP_SLOT_ELEMENT_BUF, "verts"},
608          {BMO_OP_SLOT_ELEMENT_BUF, "edgeout"},
609          {0} /* null-terminating sentine */},
610         connectverts_exec,
611         BMO_OP_FLAG_UNTAN_MULTIRES
612 };
613
614 static BMOpDefine def_extrudefaceregion = {
615         "extrudefaceregion",
616         {{BMO_OP_SLOT_ELEMENT_BUF, "edgefacein"},
617          {BMO_OP_SLOT_MAPPING, "exclude"},
618          {BMO_OP_SLOT_INT, "alwayskeeporig"},
619          {BMO_OP_SLOT_ELEMENT_BUF, "geomout"},
620          {0} /* null-terminating sentine */},
621         extrude_edge_context_exec,
622         0
623 };
624
625 static BMOpDefine def_dissolvevertsop = {
626         "dissolveverts",
627         {{BMO_OP_SLOT_ELEMENT_BUF, "verts"},
628          {0} /* null-terminating sentine */},
629         dissolveverts_exec,
630         BMO_OP_FLAG_UNTAN_MULTIRES
631 };
632
633 static BMOpDefine def_dissolveedgessop = {
634         "dissolveedges",
635         {{BMO_OP_SLOT_ELEMENT_BUF, "edges"},
636          {BMO_OP_SLOT_ELEMENT_BUF, "regionout"},
637          {BMO_OP_SLOT_INT, "use_verts"}, // dissolve verts left between only 2 edges.
638          {0} /* null-terminating sentine */},
639         dissolveedges_exec,
640         BMO_OP_FLAG_UNTAN_MULTIRES
641 };
642
643 static BMOpDefine def_dissolveedgeloopsop = {
644         "dissolveedgeloop",
645         {{BMO_OP_SLOT_ELEMENT_BUF, "edges"},
646          {BMO_OP_SLOT_ELEMENT_BUF, "regionout"},
647          {0} /* null-terminating sentine */},
648         dissolve_edgeloop_exec,
649         BMO_OP_FLAG_UNTAN_MULTIRES
650 };
651
652 static BMOpDefine def_dissolvefacesop = {
653         "dissolvefaces",
654         {{BMO_OP_SLOT_ELEMENT_BUF, "faces"},
655          {BMO_OP_SLOT_ELEMENT_BUF, "regionout"},
656          {BMO_OP_SLOT_INT, "use_verts"}, // dissolve verts left between only 2 edges.
657          {0} /* null-terminating sentine */},
658         dissolvefaces_exec,
659         BMO_OP_FLAG_UNTAN_MULTIRES
660 };
661
662 static BMOpDefine def_dissolvelimitop = {
663         "dissolvelimit",
664         {{BMO_OP_SLOT_FLT, "angle_limit"}, /* total rotation angle (degrees) */
665          {BMO_OP_SLOT_ELEMENT_BUF, "verts"},
666          {BMO_OP_SLOT_ELEMENT_BUF, "edges"},
667          {0} /* null-terminating sentine */},
668         dissolvelimit_exec,
669         BMO_OP_FLAG_UNTAN_MULTIRES
670 };
671
672 static BMOpDefine def_triangop = {
673         "triangulate",
674         {{BMO_OP_SLOT_ELEMENT_BUF, "faces"},
675          {BMO_OP_SLOT_ELEMENT_BUF, "edgeout"},
676          {BMO_OP_SLOT_ELEMENT_BUF, "faceout"},
677          {BMO_OP_SLOT_MAPPING, "facemap"},
678          {0} /* null-terminating sentine */},
679         triangulate_exec,
680         BMO_OP_FLAG_UNTAN_MULTIRES
681 };
682
683 static BMOpDefine def_subdop = {
684         "esubd",
685         {{BMO_OP_SLOT_ELEMENT_BUF, "edges"},
686          {BMO_OP_SLOT_INT, "numcuts"},
687          {BMO_OP_SLOT_FLT, "smooth"},
688          {BMO_OP_SLOT_FLT, "fractal"},
689          {BMO_OP_SLOT_INT, "beauty"},
690          {BMO_OP_SLOT_INT, "seed"},
691          {BMO_OP_SLOT_MAPPING, "custompatterns"},
692          {BMO_OP_SLOT_MAPPING, "edgepercents"},
693
694         /* these next three can have multiple types of elements in them */
695          {BMO_OP_SLOT_ELEMENT_BUF, "outinner"},
696          {BMO_OP_SLOT_ELEMENT_BUF, "outsplit"},
697          {BMO_OP_SLOT_ELEMENT_BUF, "geomout"}, /* contains all output geometr */
698
699          {BMO_OP_SLOT_INT, "quadcornertype"}, //quad corner type, see bmesh_operators.h
700          {BMO_OP_SLOT_INT, "gridfill"}, //fill in fully-selected faces with a grid
701          {BMO_OP_SLOT_INT, "singleedge"}, //tesselate the case of one edge selected in a quad or triangle
702
703          {0} /* null-terminating sentine */,
704         },
705         esubdivide_exec,
706         BMO_OP_FLAG_UNTAN_MULTIRES
707 };
708
709 static BMOpDefine def_delop = {
710         "del",
711         {{BMO_OP_SLOT_ELEMENT_BUF, "geom"}, {BMO_OP_SLOT_INT, "context"},
712          {0} /* null-terminating sentine */},
713         delop_exec,
714         0
715 };
716
717 static BMOpDefine def_dupeop = {
718         "dupe",
719         {{BMO_OP_SLOT_ELEMENT_BUF, "geom"},
720          {BMO_OP_SLOT_ELEMENT_BUF, "origout"},
721          {BMO_OP_SLOT_ELEMENT_BUF, "newout"},
722         /* facemap maps from source faces to dupe
723          * faces, and from dupe faces to source faces */
724          {BMO_OP_SLOT_MAPPING, "facemap"},
725          {BMO_OP_SLOT_MAPPING, "boundarymap"},
726          {BMO_OP_SLOT_MAPPING, "isovertmap"},
727          {BMO_OP_SLOT_PNT, "dest"}, /* destination bmesh, if NULL will use current on */
728          {0} /* null-terminating sentine */},
729         dupeop_exec,
730         0
731 };
732
733 static BMOpDefine def_splitop = {
734         "split",
735         {{BMO_OP_SLOT_ELEMENT_BUF, "geom"},
736          {BMO_OP_SLOT_ELEMENT_BUF, "geomout"},
737          {BMO_OP_SLOT_MAPPING, "boundarymap"},
738          {BMO_OP_SLOT_MAPPING, "isovertmap"},
739          {BMO_OP_SLOT_PNT, "dest"}, /* destination bmesh, if NULL will use current on */
740          {0} /* null-terminating sentine */},
741         splitop_exec,
742         0
743 };
744
745 /*
746  * Spin
747  *
748  * Extrude or duplicate geometry a number of times,
749  * rotating and possibly translating after each step
750  */
751 static BMOpDefine def_spinop = {
752         "spin",
753         {{BMO_OP_SLOT_ELEMENT_BUF, "geom"},
754          {BMO_OP_SLOT_ELEMENT_BUF, "lastout"}, /* result of last step */
755          {BMO_OP_SLOT_VEC, "cent"}, /* rotation center */
756          {BMO_OP_SLOT_VEC, "axis"}, /* rotation axis */
757          {BMO_OP_SLOT_VEC, "dvec"}, /* translation delta per step */
758          {BMO_OP_SLOT_FLT, "ang"}, /* total rotation angle (degrees) */
759          {BMO_OP_SLOT_INT, "steps"}, /* number of steps */
760          {BMO_OP_SLOT_INT, "dupli"}, /* duplicate or extrude? */
761          {0} /* null-terminating sentine */},
762         spinop_exec,
763         0
764 };
765
766
767 /*
768  * Similar faces search
769  *
770  * Find similar faces (area/material/perimeter, ...).
771  */
772 static BMOpDefine def_similarfaces = {
773         "similarfaces",
774         {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
775          {BMO_OP_SLOT_ELEMENT_BUF, "faceout"}, /* output faces */
776          {BMO_OP_SLOT_INT, "type"},                     /* type of selection */
777          {BMO_OP_SLOT_FLT, "thresh"},           /* threshold of selection */
778          {0} /* null-terminating sentine */},
779         bmesh_similarfaces_exec,
780         0
781 };
782
783 /*
784  * Similar edges search
785  *
786  *  Find similar edges (length, direction, edge, seam, ...).
787  */
788 static BMOpDefine def_similaredges = {
789         "similaredges",
790         {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edges */
791          {BMO_OP_SLOT_ELEMENT_BUF, "edgeout"}, /* output edges */
792          {BMO_OP_SLOT_INT, "type"},                     /* type of selection */
793          {BMO_OP_SLOT_FLT, "thresh"},           /* threshold of selection */
794          {0} /* null-terminating sentine */},
795         bmesh_similaredges_exec,
796         0
797 };
798
799 /*
800  * Similar vertices search
801  *
802  * Find similar vertices (normal, face, vertex group, ...).
803  */
804 static BMOpDefine def_similarverts = {
805         "similarverts",
806         {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */
807          {BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, /* output vertices */
808          {BMO_OP_SLOT_INT, "type"},                     /* type of selection */
809          {BMO_OP_SLOT_FLT, "thresh"},           /* threshold of selection */
810          {0} /* null-terminating sentine */},
811         bmesh_similarverts_exec,
812         0
813 };
814
815 /*
816  * uv rotation
817  * cycle the uvs
818  */
819 static BMOpDefine def_meshrotateuvs = {
820         "meshrotateuvs",
821         {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
822          {BMO_OP_SLOT_INT, "dir"},                      /* direction */
823          {0} /* null-terminating sentine */},
824         bmesh_rotateuvs_exec,
825         0
826 };
827
828 /*
829  * uv reverse
830  * reverse the uvs
831  */
832 static BMOpDefine def_meshreverseuvs = {
833         "meshreverseuvs",
834         {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
835          {0} /* null-terminating sentine */},
836         bmesh_reverseuvs_exec,
837         0
838 };
839
840 /*
841  * color rotation
842  * cycle the colors
843  */
844 static BMOpDefine def_meshrotatecolors = {
845         "meshrotatecolors",
846         {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
847          {BMO_OP_SLOT_INT, "dir"},                      /* direction */
848          {0} /* null-terminating sentine */},
849         bmesh_rotatecolors_exec,
850         0
851 };
852
853 /*
854  * color reverse
855  * reverse the colors
856  */
857 static BMOpDefine def_meshreversecolors = {
858         "meshreversecolors",
859         {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
860          {0} /* null-terminating sentine */},
861         bmesh_reversecolors_exec,
862         0
863 };
864
865 /*
866  * Similar vertices search
867  *
868  * Find similar vertices (normal, face, vertex group, ...).
869  */
870 static BMOpDefine def_vertexshortestpath = {
871         "vertexshortestpath",
872         {{BMO_OP_SLOT_ELEMENT_BUF, "startv"}, /* start vertex */
873          {BMO_OP_SLOT_ELEMENT_BUF, "endv"}, /* end vertex */
874          {BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, /* output vertices */
875          {BMO_OP_SLOT_INT, "type"},                     /* type of selection */
876          {0} /* null-terminating sentine */},
877         bmesh_vertexshortestpath_exec,
878         0
879 };
880
881 /*
882  * Edge Split
883  *
884  * Disconnects faces along input edges.
885  */
886 static BMOpDefine def_edgesplit = {
887         "edgesplit",
888         {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edges */
889          {BMO_OP_SLOT_ELEMENT_BUF, "edgeout1"}, /* old output disconnected edges */
890          {BMO_OP_SLOT_ELEMENT_BUF, "edgeout2"}, /* new output disconnected edges */
891          {0} /* null-terminating sentine */},
892         bmesh_edgesplitop_exec,
893         BMO_OP_FLAG_UNTAN_MULTIRES
894 };
895
896 /*
897  * Create Grid
898  *
899  * Creates a grid with a variable number of subdivisions
900  */
901 static BMOpDefine def_create_grid = {
902         "create_grid",
903         {{BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, //output verts
904          {BMO_OP_SLOT_INT,         "xsegments"}, //number of x segments
905          {BMO_OP_SLOT_INT,         "ysegments"}, //number of y segments
906          {BMO_OP_SLOT_FLT,         "size"}, //size of the grid
907          {BMO_OP_SLOT_MAT,         "mat"}, //matrix to multiply the new geometry with
908          {0, /* null-terminating sentine */}},
909         bmesh_create_grid_exec,
910         0,
911 };
912
913 /*
914  * Create UV Sphere
915  *
916  * Creates a grid with a variable number of subdivisions
917  */
918 static BMOpDefine def_create_uvsphere = {
919         "create_uvsphere",
920         {{BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, //output verts
921          {BMO_OP_SLOT_INT,         "segments"}, //number of u segments
922          {BMO_OP_SLOT_INT,         "revolutions"}, //number of v segment
923          {BMO_OP_SLOT_FLT,         "diameter"}, //diameter
924          {BMO_OP_SLOT_MAT,         "mat"}, //matrix to multiply the new geometry with--
925          {0, /* null-terminating sentine */}},
926         bmesh_create_uvsphere_exec,
927         0,
928 };
929
930 /*
931  * Create Ico Sphere
932  *
933  * Creates a grid with a variable number of subdivisions
934  */
935 static BMOpDefine def_create_icosphere = {
936         "create_icosphere",
937         {{BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, //output verts
938          {BMO_OP_SLOT_INT,         "subdivisions"}, //how many times to recursively subdivide the sphere
939          {BMO_OP_SLOT_FLT,         "diameter"}, //diameter
940          {BMO_OP_SLOT_MAT,         "mat"}, //matrix to multiply the new geometry with
941          {0, /* null-terminating sentine */}},
942         bmesh_create_icosphere_exec,
943         0,
944 };
945
946 /*
947  * Create Suzanne
948  *
949  * Creates a monkey.  Be wary.
950  */
951 static BMOpDefine def_create_monkey = {
952         "create_monkey",
953         {{BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, //output verts
954          {BMO_OP_SLOT_MAT, "mat"}, //matrix to multiply the new geometry with--
955          {0, /* null-terminating sentine */}},
956         bmesh_create_monkey_exec,
957         0,
958 };
959
960 /*
961  * Create Cone
962  *
963  * Creates a cone with variable depth at both ends
964  */
965 static BMOpDefine def_create_cone = {
966         "create_cone",
967         {{BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, //output verts
968          {BMO_OP_SLOT_INT, "cap_ends"}, //wheter or not to fill in the ends with faces
969          {BMO_OP_SLOT_INT, "cap_tris"}, //fill ends with triangles instead of ngons
970          {BMO_OP_SLOT_INT, "segments"},
971          {BMO_OP_SLOT_FLT, "diameter1"}, //diameter of one end
972          {BMO_OP_SLOT_FLT, "diameter2"}, //diameter of the opposite
973          {BMO_OP_SLOT_FLT, "depth"}, //distance between ends
974          {BMO_OP_SLOT_MAT, "mat"}, //matrix to multiply the new geometry with--
975          {0, /* null-terminating sentine */}},
976         bmesh_create_cone_exec,
977         0,
978 };
979
980 /*
981  * Creates a circle
982  */
983 static BMOpDefine def_create_circle = {
984         "create_circle",
985         {{BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, //output verts
986          {BMO_OP_SLOT_INT, "cap_ends"}, //wheter or not to fill in the ends with faces
987          {BMO_OP_SLOT_INT, "cap_tris"}, //fill ends with triangles instead of ngons
988          {BMO_OP_SLOT_INT, "segments"},
989          {BMO_OP_SLOT_FLT, "diameter"}, //diameter of one end
990          {BMO_OP_SLOT_MAT, "mat"}, //matrix to multiply the new geometry with--
991          {0, /* null-terminating sentine */}},
992         bmesh_create_circle_exec,
993         0,
994 };
995
996 /*
997  * Create Cone
998  *
999  * Creates a cone with variable depth at both ends
1000  */
1001 static BMOpDefine def_create_cube = {
1002         "create_cube",
1003         {{BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, //output verts
1004          {BMO_OP_SLOT_FLT, "size"}, //size of the cube
1005          {BMO_OP_SLOT_MAT, "mat"}, //matrix to multiply the new geometry with--
1006          {0, /* null-terminating sentine */}},
1007         bmesh_create_cube_exec,
1008         0,
1009 };
1010
1011 /*
1012  * Bevel
1013  *
1014  * Bevels edges and vertices
1015  */
1016 static BMOpDefine def_bevel = {
1017         "bevel",
1018         {{BMO_OP_SLOT_ELEMENT_BUF, "geom"}, /* input edges and vertices */
1019          {BMO_OP_SLOT_ELEMENT_BUF, "face_spans"}, /* new geometry */
1020          {BMO_OP_SLOT_ELEMENT_BUF, "face_holes"}, /* new geometry */
1021          {BMO_OP_SLOT_INT, "use_lengths"}, /* grab edge lengths from a PROP_FLT customdata laye */
1022          {BMO_OP_SLOT_INT, "use_even"}, /* corner vert placement: use shell/angle calculations  */
1023          {BMO_OP_SLOT_INT, "use_dist"}, /* corner vert placement: evaluate percent as a distance,
1024                                          * modifier uses this. We could do this as another float setting */
1025          {BMO_OP_SLOT_INT, "lengthlayer"}, /* which PROP_FLT layer to us */
1026          {BMO_OP_SLOT_FLT, "percent"}, /* percentage to expand bevelled edge */
1027          {0} /* null-terminating sentine */},
1028         bmesh_bevel_exec,
1029         BMO_OP_FLAG_UNTAN_MULTIRES
1030 };
1031
1032 /*
1033  * Beautify Fill
1034  *
1035  * Makes triangle a bit nicer
1036  */
1037 static BMOpDefine def_beautify_fill = {
1038 "beautify_fill",
1039         {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
1040          {BMO_OP_SLOT_ELEMENT_BUF, "constrain_edges"}, /* edges that can't be flipped */
1041          {BMO_OP_SLOT_ELEMENT_BUF, "geomout"}, /* new flipped faces and edges */
1042          {0} /* null-terminating sentine */},
1043         bmesh_beautify_fill_exec,
1044         BMO_OP_FLAG_UNTAN_MULTIRES
1045 };
1046
1047 /*
1048  * Triangle Fill
1049  *
1050  * Fill edges with triangles
1051  */
1052 static BMOpDefine def_triangle_fill = {
1053         "triangle_fill",
1054         {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edges */
1055          {BMO_OP_SLOT_ELEMENT_BUF, "geomout"}, /* new faces and edges */
1056          {0} /* null-terminating sentine */},
1057         bmesh_triangle_fill_exec,
1058         BMO_OP_FLAG_UNTAN_MULTIRES
1059 };
1060
1061 /*
1062  * Solidify
1063  *
1064  * Turns a mesh into a shell with thickness
1065  */
1066 static BMOpDefine def_solidify = {
1067         "solidify",
1068         {{BMO_OP_SLOT_ELEMENT_BUF, "geom"},
1069          {BMO_OP_SLOT_FLT, "thickness"},
1070          {BMO_OP_SLOT_ELEMENT_BUF, "geomout"},
1071          {0}},
1072         bmesh_solidify_face_region_exec,
1073         0
1074 };
1075
1076 BMOpDefine *opdefines[] = {
1077         &def_splitop,
1078         &def_spinop,
1079         &def_dupeop,
1080         &def_delop,
1081         &def_subdop,
1082         &def_triangop,
1083         &def_dissolvefacesop,
1084         &def_dissolveedgessop,
1085         &def_dissolveedgeloopsop,
1086         &def_dissolvevertsop,
1087     &def_dissolvelimitop,
1088         &def_extrudefaceregion,
1089         &def_connectverts,
1090         //&def_makeprim,
1091         &def_extrudeverts_indiv,
1092         &def_mesh_to_bmesh,
1093         &def_object_load_bmesh,
1094         &def_transform,
1095         &def_translate,
1096         &def_rotate,
1097         &def_edgenet_fill,
1098         &def_contextual_create,
1099         &def_makevert,
1100         &def_weldverts,
1101         &def_removedoubles,
1102         &def_finddoubles,
1103         &def_mirror,
1104         &def_edgebisect,
1105         &def_reversefaces,
1106         &def_edgerotate,
1107         &def_regionextend,
1108         &def_righthandfaces,
1109         &def_vertexsmooth,
1110         &def_extrude_onlyedge,
1111         &def_extrude_indivface,
1112         &def_collapse_uvs,
1113         &def_pointmerge,
1114         &def_collapse,
1115         &def_similarfaces,
1116         &def_similaredges,
1117         &def_similarverts,
1118         &def_pointmerge_facedata,
1119         &def_vert_average_facedata,
1120         &def_meshrotateuvs,
1121         &def_bmesh_to_mesh,
1122         &def_meshreverseuvs,
1123         &def_edgenet_prepare,
1124         &def_meshrotatecolors,
1125         &def_meshreversecolors,
1126         &def_vertexshortestpath,
1127         &def_scale,
1128         &def_edgesplit,
1129         &def_automerge,
1130         &def_create_uvsphere,
1131         &def_create_grid,
1132         &def_create_icosphere,
1133         &def_create_monkey,
1134         &def_create_cube,
1135         &def_create_circle,
1136         &def_create_cone,
1137         &def_join_triangles,
1138         &def_bevel,
1139         &def_beautify_fill,
1140         &def_triangle_fill,
1141         &def_bridge_loops,
1142         &def_solidify,
1143 };
1144
1145 int bmesh_total_ops = (sizeof(opdefines) / sizeof(void *));