commit before doing some hefty shapekey change, will break compilation
[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) do 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 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 BMOpDefine def_righthandfaces = {
94         "righthandfaces",
95         {{BMOP_OPSLOT_ELEMENT_BUF, "faces"},
96         {0} /*null-terminating sentinel*/,
97         },
98         bmesh_righthandfaces_exec,
99         0
100 };
101
102 /*
103   Region Extend
104   
105   used to implement the select more/less tools.
106   this puts some geometry surrounding regions of
107   geometry in geom into geomout.
108   
109   if usefaces is 0 then geomout spits out verts and edges, 
110   otherwise it spits out faces.
111   */
112 BMOpDefine def_regionextend = {
113         "regionextend",
114         {{BMOP_OPSLOT_ELEMENT_BUF, "geom"}, //input geometry
115          {BMOP_OPSLOT_ELEMENT_BUF, "geomout"}, //output slot, computed boundary geometry.
116          {BMOP_OPSLOT_INT, "constrict"}, //find boundary inside the regions, not outside.
117          {BMOP_OPSLOT_INT, "usefaces"}, //extend from faces instead of edges
118         {0} /*null-terminating sentinel*/,
119         },
120         bmesh_regionextend_exec,
121         0
122 };
123
124 /*
125   Edge Rotate
126
127   Rotates edges topologically.  Also known as "spin edge" to some people.
128   Simple example: [/] becomes [|] then [\].
129 */
130 BMOpDefine def_edgerotate = {
131         "edgerotate",
132         {{BMOP_OPSLOT_ELEMENT_BUF, "edges"}, //input edges
133          {BMOP_OPSLOT_ELEMENT_BUF, "edgeout"}, //newly spun edges
134          {BMOP_OPSLOT_INT, "ccw"}, //rotate edge counter-clockwise if true, othewise clockwise
135         {0} /*null-terminating sentinel*/,
136         },
137         bmesh_edgerotate_exec,
138         0
139 };
140
141 /*
142   Reverse Faces
143
144   Reverses the winding (vertex order) of faces.  This has the effect of
145   flipping the normal.
146 */
147 BMOpDefine def_reversefaces = {
148         "reversefaces",
149         {{BMOP_OPSLOT_ELEMENT_BUF, "faces"}, //input faces
150         {0} /*null-terminating sentinel*/,
151         },
152         bmesh_reversefaces_exec,
153         0
154 };
155
156 /*
157   Edge Bisect
158
159   Splits input edges (but doesn't do anything else).
160   This creates a 2-valence vert.
161 */
162 BMOpDefine def_edgebisect = {
163         "edgebisect",
164         {{BMOP_OPSLOT_ELEMENT_BUF, "edges"}, //input edges
165         {BMOP_OPSLOT_INT, "numcuts"}, //number of cuts
166         {BMOP_OPSLOT_ELEMENT_BUF, "outsplit"}, //newly created vertices and edges
167         {0} /*null-terminating sentinel*/,
168         },
169         esplit_exec,
170         0
171 };
172
173 /*
174   Mirror
175
176   Mirrors geometry along an axis.  The resulting geometry is welded on using
177   mergedist.  Pairs of original/mirrored vertices are welded using the mergedist
178   parameter (which defines the minimum distance for welding to happen).
179 */
180
181 BMOpDefine def_mirror = {
182         "mirror",
183         {{BMOP_OPSLOT_ELEMENT_BUF, "geom"}, //input geometry
184          {BMOP_OPSLOT_MAT, "mat"}, //matrix defining the mirror transformation
185          {BMOP_OPSLOT_FLT, "mergedist"}, //maximum distance for merging.  does no merging if 0.
186          {BMOP_OPSLOT_ELEMENT_BUF, "newout"}, //output geometry, mirrored
187          {BMOP_OPSLOT_INT,         "axis"}, //the axis to use, 0, 1, or 2 for x, y, z
188          {BMOP_OPSLOT_INT,         "mirror_u"}, //mirror UVs across the u axis
189          {BMOP_OPSLOT_INT,         "mirror_v"}, //mirror UVs across the v axis
190          {0, /*null-terminating sentinel*/}},
191         bmesh_mirror_exec,
192         0,
193 };
194
195 /*
196   Find Doubles
197
198   Takes input verts and find vertices they should weld to.  Outputs a
199   mapping slot suitable for use with the weld verts bmop.
200 */
201 BMOpDefine def_finddoubles = {
202         "finddoubles",
203         {{BMOP_OPSLOT_ELEMENT_BUF, "verts"}, //input vertices
204          {BMOP_OPSLOT_ELEMENT_BUF, "keepverts"}, //list of verts to keep
205          {BMOP_OPSLOT_FLT,         "dist"}, //minimum distance
206          {BMOP_OPSLOT_MAPPING, "targetmapout"},
207          {0, /*null-terminating sentinel*/}},
208         bmesh_finddoubles_exec,
209         0,
210 };
211
212 /*
213   Remove Doubles
214
215   Finds groups of vertices closer then dist and merges them together,
216   using the weld verts bmop.
217 */
218 BMOpDefine def_removedoubles = {
219         "removedoubles",
220         {{BMOP_OPSLOT_ELEMENT_BUF, "verts"}, //input verts
221          {BMOP_OPSLOT_FLT,         "dist"}, //minimum distance
222          {0, /*null-terminating sentinel*/}},
223         bmesh_removedoubles_exec,
224         0,
225 };
226
227 /*
228   Auto Merge
229
230   Finds groups of vertices closer then dist and merges them together,
231   using the weld verts bmop.  The merges must go from a vert not in
232   verts to one in verts.
233 */
234 BMOpDefine def_automerge = {
235         "automerge",
236         {{BMOP_OPSLOT_ELEMENT_BUF, "verts"}, //input verts
237          {BMOP_OPSLOT_FLT,         "dist"}, //minimum distance
238          {0, /*null-terminating sentinel*/}},
239         bmesh_automerge_exec,
240         0,
241 };
242
243 /*
244   Collapse Connected
245
246   Collapses connected vertices
247 */
248 BMOpDefine def_collapse = {
249         "collapse",
250         {{BMOP_OPSLOT_ELEMENT_BUF, "edges"}, /*input edges*/
251          {0, /*null-terminating sentinel*/}},
252         bmesh_collapse_exec,
253         0,
254 };
255
256
257 /*
258   Facedata point Merge
259
260   Merge uv/vcols at a specific vertex.
261 */
262 BMOpDefine def_pointmerge_facedata = {
263         "pointmerge_facedata",
264         {{BMOP_OPSLOT_ELEMENT_BUF, "verts"}, /*input vertices*/
265          {BMOP_OPSLOT_ELEMENT_BUF, "snapv"}, /*snap vertex*/
266          {0, /*null-terminating sentinel*/}},
267         bmesh_pointmerge_facedata_exec,
268         0,
269 };
270
271 /*
272   Average Vertices Facevert Data
273
274   Merge uv/vcols associated with the input vertices at
275   the bounding box center. (I know, it's not averaging but
276   the vert_snap_to_bb_center is just too long).
277 */
278 BMOpDefine def_vert_average_facedata = {
279         "vert_average_facedata",
280         {{BMOP_OPSLOT_ELEMENT_BUF, "verts"}, /*input vertices*/
281          {0, /*null-terminating sentinel*/}},
282         bmesh_vert_average_facedata_exec,
283         0,
284 };
285
286 /*
287   Point Merge
288
289   Merge verts together at a point.
290 */
291 BMOpDefine def_pointmerge = {
292         "pointmerge",
293         {{BMOP_OPSLOT_ELEMENT_BUF, "verts"}, /*input vertices*/
294          {BMOP_OPSLOT_VEC,         "mergeco"},
295          {0, /*null-terminating sentinel*/}},
296         bmesh_pointmerge_exec,
297         0,
298 };
299
300 /*
301   Collapse Connected UVs
302
303   Collapses connected UV vertices.
304 */
305 BMOpDefine def_collapse_uvs = {
306         "collapse_uvs",
307         {{BMOP_OPSLOT_ELEMENT_BUF, "edges"}, /*input edges*/
308          {0, /*null-terminating sentinel*/}},
309         bmesh_collapsecon_exec,
310         0,
311 };
312
313 /*
314   Weld Verts
315
316   Welds verts together (kindof like remove doubles, merge, etc, all of which
317   use or will use this bmop).  You pass in mappings from vertices to the vertices
318   they weld with.
319 */
320 BMOpDefine def_weldverts = {
321         "weldverts",
322         {{BMOP_OPSLOT_MAPPING, "targetmap"}, /*maps welded vertices to verts they should weld to.*/
323          {0, /*null-terminating sentinel*/}},
324         bmesh_weldverts_exec,
325         0,
326 };
327
328 /*
329   Make Vertex
330
331   Creates a single vertex; this bmop was necassary
332   for click-create-vertex.
333 */
334 BMOpDefine def_makevert = {
335         "makevert",
336         {{BMOP_OPSLOT_VEC, "co"}, //the coordinate of the new vert
337         {BMOP_OPSLOT_ELEMENT_BUF, "newvertout"}, //the new vert
338         {0, /*null-terminating sentinel*/}},
339         bmesh_makevert_exec,
340         0,
341 };
342
343 /*
344   Contextual Create
345
346   This is basically fkey, it creates
347   new faces from vertices, makes stuff from edge nets,
348   makes wire edges, etc.  It also dissolves
349   faces.
350   
351   Three verts become a triangle, four become a quad.  Two
352   become a wire edge.
353   */
354 BMOpDefine def_contextual_create= {
355         "contextual_create",
356         {{BMOP_OPSLOT_ELEMENT_BUF, "geom"}, //input geometry.
357          {BMOP_OPSLOT_ELEMENT_BUF, "faceout"}, //newly-made face(s)
358          {0, /*null-terminating sentinel*/}},
359         bmesh_contextual_create_exec,
360         0,
361 };
362
363 BMOpDefine def_edgenet_fill= {
364         "edgenet_fill",
365         {{BMOP_OPSLOT_ELEMENT_BUF, "edges"},
366          {BMOP_OPSLOT_ELEMENT_BUF, "faceout"},
367         {0, /*null-terminating sentinel*/}},
368         bmesh_edgenet_fill_exec,
369         0,
370 };
371
372 /*
373   Edgenet Prepare
374
375   Identifies several useful edge loop cases and modifies them so
376   they'll become a face when edgenet_fill is called.  The cases covered are:
377
378   * One single loop; an edge is added to connect the ends
379   * Two loops; two edges are added to connect the endpoints (based on the
380     shortest distance between each endpont).
381 */
382 BMOpDefine def_edgenet_prepare= {
383         "edgenet_prepare",
384         {{BMOP_OPSLOT_ELEMENT_BUF, "edges"}, //input edges
385          {BMOP_OPSLOT_ELEMENT_BUF, "edgeout"}, //new edges
386         {0, /*null-terminating sentinel*/}},
387         bmesh_edgenet_prepare,
388         0,
389 };
390
391 /*
392   Rotate
393
394   Rotate vertices around a center, using a 3x3 rotation
395   matrix.  Equivilent of the old rotateflag function.
396 */
397 BMOpDefine def_rotate = {
398         "rotate",
399         {{BMOP_OPSLOT_VEC, "cent"}, //center of rotation
400          {BMOP_OPSLOT_MAT, "mat"}, //matrix defining rotation
401         {BMOP_OPSLOT_ELEMENT_BUF, "verts"}, //input vertices
402         {0, /*null-terminating sentinel*/}},
403         bmesh_rotate_exec,
404         0,
405 };
406
407 /*
408   Translate
409
410   Translate vertices by an offset.  Equivelent of the
411   old translateflag function.
412 */
413 BMOpDefine def_translate= {
414         "translate",
415         {{BMOP_OPSLOT_VEC, "vec"}, //translation offset
416         {BMOP_OPSLOT_ELEMENT_BUF, "verts"}, //input vertices
417         {0, /*null-terminating sentinel*/}},
418         bmesh_translate_exec,
419         0,
420 };
421
422 /*
423   Scale
424
425   Scales vertices by an offset.
426 */
427 BMOpDefine def_scale= {
428         "scale",
429         {{BMOP_OPSLOT_VEC, "vec"}, //scale factor
430         {BMOP_OPSLOT_ELEMENT_BUF, "verts"}, //input vertices
431         {0, /*null-terminating sentinel*/}},
432         bmesh_scale_exec,
433         0,
434 };
435
436
437 /*
438   Transform
439
440   Transforms a set of vertices by a matrix.  Multiplies
441   the vertex coordinates with the matrix.
442 */
443 BMOpDefine def_transform = {
444         "transform",
445         {{BMOP_OPSLOT_MAT, "mat"}, //transform matrix
446         {BMOP_OPSLOT_ELEMENT_BUF, "verts"}, //input vertices
447         {0, /*null-terminating sentinel*/}},
448         bmesh_transform_exec,
449         0,
450 };
451
452 /*
453   Object Load BMesh
454
455   Loads a bmesh into an object/mesh.  This is a "private"
456   bmop.
457 */
458 BMOpDefine def_object_load_bmesh = {
459         "object_load_bmesh",
460         {{BMOP_OPSLOT_PNT, "scene"},
461         {BMOP_OPSLOT_PNT, "object"},
462         {0, /*null-terminating sentinel*/}},
463         object_load_bmesh_exec,
464         0,
465 };
466
467
468 /*
469   BMesh to Mesh
470
471   Converts a bmesh to a Mesh.  This is reserved for exiting editmode.
472 */
473 BMOpDefine def_bmesh_to_mesh = {
474         "bmesh_to_mesh",
475         {{BMOP_OPSLOT_PNT, "mesh"}, //pointer to a mesh structure to fill in
476          {BMOP_OPSLOT_PNT, "object"}, //pointer to an object structure
477          {BMOP_OPSLOT_INT, "notesselation"}, //don't calculate mfaces
478          {0, /*null-terminating sentinel*/}},
479         bmesh_to_mesh_exec,
480         0,
481 };
482
483 /*
484   Mesh to BMesh
485
486   Load the contents of a mesh into the bmesh.  this bmop is private, it's
487   reserved exclusively for entering editmode.
488 */
489 BMOpDefine def_mesh_to_bmesh = {
490         "mesh_to_bmesh",
491         {{BMOP_OPSLOT_PNT, "mesh"}, //pointer to a Mesh structure
492          {BMOP_OPSLOT_PNT, "object"}, //pointer to an Object structure
493          {0, /*null-terminating sentinel*/}},
494         mesh_to_bmesh_exec,
495         0
496 };
497
498 /*
499   Individual Face Extrude
500
501   Extrudes faces individually.
502 */
503 BMOpDefine def_extrude_indivface = {
504         "extrude_face_indiv",
505         {{BMOP_OPSLOT_ELEMENT_BUF, "faces"}, //input faces
506         {BMOP_OPSLOT_ELEMENT_BUF, "faceout"}, //output faces
507         {BMOP_OPSLOT_ELEMENT_BUF, "skirtout"}, //output skirt geometry, faces and edges
508         {0} /*null-terminating sentinel*/},
509         bmesh_extrude_face_indiv_exec,
510         0
511 };
512
513 /*
514   Extrude Only Edges
515
516   Extrudes Edges into faces, note that this is very simple, there's no fancy
517   winged extrusion.
518 */
519 BMOpDefine def_extrude_onlyedge = {
520         "extrude_edge_only",
521         {{BMOP_OPSLOT_ELEMENT_BUF, "edges"}, //input vertices
522         {BMOP_OPSLOT_ELEMENT_BUF, "geomout"}, //output geometry
523         {0} /*null-terminating sentinel*/},
524         bmesh_extrude_onlyedge_exec,
525         0
526 };
527
528 /*
529   Individual Vertex Extrude
530
531   Extrudes wire edges from vertices.
532 */
533 BMOpDefine def_extrudeverts_indiv = {
534         "extrude_vert_indiv",
535         {{BMOP_OPSLOT_ELEMENT_BUF, "verts"}, //input vertices
536         {BMOP_OPSLOT_ELEMENT_BUF, "edgeout"}, //output wire edges
537         {BMOP_OPSLOT_ELEMENT_BUF, "vertout"}, //output vertices
538         {0} /*null-terminating sentinel*/},
539         extrude_vert_indiv_exec,
540         0
541 };
542
543 #if 0
544 BMOpDefine def_makeprim = {
545         "makeprim",
546         {{BMOP_OPSLOT_INT, "type"},
547         {BMOP_OPSLOT_INT, "tot", /*rows/cols also applies to spheres*/
548         {BMOP_OPSLOT_INT, "seg",
549         {BMOP_OPSLOT_INT, "subdiv"},
550         {BMOP_OPSLOT_INT, "ext"},
551         {BMOP_OPSLOT_INT, "fill"},
552         {BMOP_OPSLOT_FLT, "dia"},
553         {BMOP_OPSLOT_FLT, "depth"},
554         {BMOP_OPSLOT_PNT, "mat"},
555         {BMOP_OPSLOT_ELEMENT_BUF, "geomout"}, //won't be implemented right away
556         {0}}
557         makeprim_exec,
558         0
559 };
560 #endif
561
562 BMOpDefine def_connectverts = {
563         "connectverts",
564         {{BMOP_OPSLOT_ELEMENT_BUF, "verts"},
565         {BMOP_OPSLOT_ELEMENT_BUF, "edgeout"},
566         {0} /*null-terminating sentinel*/},
567         connectverts_exec,
568         0
569 };
570
571 BMOpDefine def_extrudefaceregion = {
572         "extrudefaceregion",
573         {{BMOP_OPSLOT_ELEMENT_BUF, "edgefacein"},
574         {BMOP_OPSLOT_MAPPING, "exclude"},
575         {BMOP_OPSLOT_ELEMENT_BUF, "geomout"},
576         {0} /*null-terminating sentinel*/},
577         extrude_edge_context_exec,
578         0
579 };
580
581 BMOpDefine def_makefgonsop = {
582         "makefgon",
583         {{BMOP_OPSLOT_INT, "trifan"}, /*use triangle fans instead of 
584                                         real interpolation*/
585          {0} /*null-terminating sentinel*/},
586         bmesh_make_fgons_exec,
587         0
588 };
589
590 BMOpDefine def_dissolvevertsop = {
591         "dissolveverts",
592         {{BMOP_OPSLOT_ELEMENT_BUF, "verts"},
593         {0} /*null-terminating sentinel*/},
594         dissolveverts_exec,
595         0
596 };
597
598 BMOpDefine def_dissolveedgessop = {
599         "dissolveedges",
600         {{BMOP_OPSLOT_ELEMENT_BUF, "edges"},
601         {BMOP_OPSLOT_ELEMENT_BUF, "regionout"},
602         {0} /*null-terminating sentinel*/},
603         dissolveedges_exec,
604         0
605 };
606
607 BMOpDefine def_dissolveedgeloopsop = {
608         "dissolveedgeloop",
609         {{BMOP_OPSLOT_ELEMENT_BUF, "edges"},
610         {BMOP_OPSLOT_ELEMENT_BUF, "regionout"},
611         {0} /*null-terminating sentinel*/},
612         dissolve_edgeloop_exec,
613         0
614 };
615
616 BMOpDefine def_dissolvefacesop = {
617         "dissolvefaces",
618         {{BMOP_OPSLOT_ELEMENT_BUF, "faces"},
619         {BMOP_OPSLOT_ELEMENT_BUF, "regionout"},
620         {0} /*null-terminating sentinel*/},
621         dissolvefaces_exec,
622         0
623 };
624
625
626 BMOpDefine def_triangop = {
627         "triangulate",
628         {{BMOP_OPSLOT_ELEMENT_BUF, "faces"},
629         {BMOP_OPSLOT_ELEMENT_BUF, "edgeout"},
630         {BMOP_OPSLOT_ELEMENT_BUF, "faceout"},
631         {BMOP_OPSLOT_MAPPING, "facemap"},
632         {0} /*null-terminating sentinel*/},
633         triangulate_exec,
634         0
635 };
636
637 BMOpDefine def_subdop = {
638         "esubd",
639         {{BMOP_OPSLOT_ELEMENT_BUF, "edges"},
640         {BMOP_OPSLOT_INT, "numcuts"},
641         {BMOP_OPSLOT_FLT, "smooth"},
642         {BMOP_OPSLOT_FLT, "fractal"},
643         {BMOP_OPSLOT_INT, "beauty"},
644         {BMOP_OPSLOT_MAPPING, "custompatterns"},
645         {BMOP_OPSLOT_MAPPING, "edgepercents"},
646         
647         /*these next two can have multiple types of elements in them.*/
648         {BMOP_OPSLOT_ELEMENT_BUF, "outinner"},
649         {BMOP_OPSLOT_ELEMENT_BUF, "outsplit"},
650
651         {BMOP_OPSLOT_INT, "quadcornertype"}, //quad corner type, see bmesh_operators.h
652         {BMOP_OPSLOT_INT, "gridfill"}, //fill in fully-selected faces with a grid
653         {BMOP_OPSLOT_INT, "singleedge"}, //tesselate the case of one edge selected in a quad or triangle
654
655         {0} /*null-terminating sentinel*/,
656         },
657         esubdivide_exec,
658         0
659 };
660
661 BMOpDefine def_edit2bmesh = {
662         "editmesh_to_bmesh",
663         {{BMOP_OPSLOT_PNT, "em"}, {BMOP_OPSLOT_MAPPING, "map"},
664         {0} /*null-terminating sentinel*/},
665         edit2bmesh_exec,
666         0
667 };
668
669 BMOpDefine def_bmesh2edit = {
670         "bmesh_to_editmesh",
671         {{BMOP_OPSLOT_PNT, "emout"},
672         {0} /*null-terminating sentinel*/},
673         bmesh2edit_exec,
674         0
675 };
676
677 BMOpDefine def_delop = {
678         "del",
679         {{BMOP_OPSLOT_ELEMENT_BUF, "geom"}, {BMOP_OPSLOT_INT, "context"},
680         {0} /*null-terminating sentinel*/},
681         delop_exec,
682         0
683 };
684
685 BMOpDefine def_dupeop = {
686         "dupe",
687         {{BMOP_OPSLOT_ELEMENT_BUF, "geom"},
688         {BMOP_OPSLOT_ELEMENT_BUF, "origout"},
689         {BMOP_OPSLOT_ELEMENT_BUF, "newout"},
690         /*facemap maps from source faces to dupe
691           faces, and from dupe faces to source faces.*/
692         {BMOP_OPSLOT_MAPPING, "facemap"},
693         {BMOP_OPSLOT_MAPPING, "boundarymap"},
694         {BMOP_OPSLOT_MAPPING, "isovertmap"},
695         {0} /*null-terminating sentinel*/},
696         dupeop_exec,
697         0
698 };
699
700 BMOpDefine def_splitop = {
701         "split",
702         {{BMOP_OPSLOT_ELEMENT_BUF, "geom"},
703         {BMOP_OPSLOT_ELEMENT_BUF, "geomout"},
704         {BMOP_OPSLOT_MAPPING, "boundarymap"},
705         {BMOP_OPSLOT_MAPPING, "isovertmap"},
706         {0} /*null-terminating sentinel*/},
707         splitop_exec,
708         0
709 };
710
711 /*
712   Similar faces select
713
714   Select similar faces (area/material/perimeter....).
715 */
716 BMOpDefine def_similarfaces = {
717         "similarfaces",
718         {{BMOP_OPSLOT_ELEMENT_BUF, "faces"}, /* input faces */
719          {BMOP_OPSLOT_ELEMENT_BUF, "faceout"}, /* output faces */
720          {BMOP_OPSLOT_INT, "type"},                     /* type of selection */
721          {BMOP_OPSLOT_FLT, "thresh"},           /* threshold of selection */
722          {0} /*null-terminating sentinel*/},
723         bmesh_similarfaces_exec,
724         0
725 };
726
727 /*
728   Similar edges select
729
730   Select similar edges (length, direction, edge, seam,....).
731 */
732 BMOpDefine def_similaredges = {
733         "similaredges",
734         {{BMOP_OPSLOT_ELEMENT_BUF, "edges"}, /* input edges */
735          {BMOP_OPSLOT_ELEMENT_BUF, "edgeout"}, /* output edges */
736          {BMOP_OPSLOT_INT, "type"},                     /* type of selection */
737          {BMOP_OPSLOT_FLT, "thresh"},           /* threshold of selection */
738          {0} /*null-terminating sentinel*/},
739         bmesh_similaredges_exec,
740         0
741 };
742
743 /*
744   Similar vertices select
745
746   Select similar vertices (normal, face, vertex group,....).
747 */
748 BMOpDefine def_similarverts = {
749         "similarverts",
750         {{BMOP_OPSLOT_ELEMENT_BUF, "verts"}, /* input vertices */
751          {BMOP_OPSLOT_ELEMENT_BUF, "vertout"}, /* output vertices */
752          {BMOP_OPSLOT_INT, "type"},                     /* type of selection */
753          {BMOP_OPSLOT_FLT, "thresh"},           /* threshold of selection */
754          {0} /*null-terminating sentinel*/},
755         bmesh_similarverts_exec,
756         0
757 };
758
759 /*
760 ** uv rotation
761 ** cycle the uvs
762 */
763 BMOpDefine def_meshrotateuvs = {
764         "meshrotateuvs",
765         {{BMOP_OPSLOT_ELEMENT_BUF, "faces"}, /* input faces */
766          {BMOP_OPSLOT_INT, "dir"},                      /* direction */
767          {0} /*null-terminating sentinel*/},
768         bmesh_rotateuvs_exec,
769         0
770 };
771
772 /*
773 ** uv reverse
774 ** reverse the uvs
775 */
776 BMOpDefine def_meshreverseuvs = {
777         "meshreverseuvs",
778         {{BMOP_OPSLOT_ELEMENT_BUF, "faces"}, /* input faces */
779          {0} /*null-terminating sentinel*/},
780         bmesh_reverseuvs_exec,
781         0
782 };
783
784 /*
785 ** color rotation
786 ** cycle the colors
787 */
788 BMOpDefine def_meshrotatecolors = {
789         "meshrotatecolors",
790         {{BMOP_OPSLOT_ELEMENT_BUF, "faces"}, /* input faces */
791          {BMOP_OPSLOT_INT, "dir"},                      /* direction */
792          {0} /*null-terminating sentinel*/},
793         bmesh_rotatecolors_exec,
794         0
795 };
796
797 /*
798 ** color reverse
799 ** reverse the colors
800 */
801 BMOpDefine def_meshreversecolors = {
802         "meshreversecolors",
803         {{BMOP_OPSLOT_ELEMENT_BUF, "faces"}, /* input faces */
804          {0} /*null-terminating sentinel*/},
805         bmesh_reversecolors_exec,
806         0
807 };
808
809 /*
810   Similar vertices select
811
812   Select similar vertices (normal, face, vertex group,....).
813 */
814 BMOpDefine def_vertexshortestpath = {
815         "vertexshortestpath",
816         {{BMOP_OPSLOT_ELEMENT_BUF, "startv"}, /* start vertex */
817          {BMOP_OPSLOT_ELEMENT_BUF, "endv"}, /* end vertex */
818          {BMOP_OPSLOT_ELEMENT_BUF, "vertout"}, /* output vertices */
819          {BMOP_OPSLOT_INT, "type"},                     /* type of selection */
820          {0} /*null-terminating sentinel*/},
821         bmesh_vertexshortestpath_exec,
822         0
823 };
824
825 /*
826   Edge Split
827
828   Disconnects faces along input edges.
829  */
830 BMOpDefine def_edgesplit = {
831         "edgesplit",
832         {{BMOP_OPSLOT_ELEMENT_BUF, "edges"}, /* input edges */
833          {BMOP_OPSLOT_ELEMENT_BUF, "edgeout1"}, /* old output disconnected edges */
834          {BMOP_OPSLOT_ELEMENT_BUF, "edgeout2"}, /* new output disconnected edges */
835          {0} /*null-terminating sentinel*/},
836         bmesh_edgesplitop_exec,
837         0
838 };
839
840 BMOpDefine *opdefines[] = {
841         &def_splitop,
842         &def_dupeop,
843         &def_delop,
844         &def_edit2bmesh,
845         &def_bmesh2edit,
846         &def_subdop,
847         &def_triangop,
848         &def_dissolvefacesop,
849         &def_dissolveedgessop,
850         &def_dissolveedgeloopsop,
851         &def_dissolvevertsop,
852         &def_makefgonsop,
853         &def_extrudefaceregion,
854         &def_connectverts,
855         //&def_makeprim,
856         &def_extrudeverts_indiv,
857         &def_mesh_to_bmesh,
858         &def_object_load_bmesh,
859         &def_transform,
860         &def_translate,
861         &def_rotate,
862         &def_edgenet_fill,
863         &def_contextual_create,
864         &def_makevert,
865         &def_weldverts,
866         &def_removedoubles,
867         &def_finddoubles,
868         &def_mirror,
869         &def_edgebisect,
870         &def_reversefaces,
871         &def_edgerotate,
872         &def_regionextend,
873         &def_righthandfaces,
874         &def_vertexsmooth,
875         &def_extrude_onlyedge,
876         &def_extrude_indivface,
877         &def_collapse_uvs,
878         &def_pointmerge,
879         &def_collapse,
880         &def_similarfaces,
881         &def_similaredges,
882         &def_similarverts,
883         &def_pointmerge_facedata,
884         &def_vert_average_facedata,
885         &def_meshrotateuvs,
886         &def_bmesh_to_mesh,
887         &def_meshreverseuvs,
888         &def_edgenet_prepare,
889         &def_meshrotatecolors,
890         &def_meshreversecolors,
891         &def_vertexshortestpath,
892         &def_scale,
893         &def_edgesplit,
894         &def_automerge,
895 };
896
897 int bmesh_total_ops = (sizeof(opdefines) / sizeof(void*));