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