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