merge with trunk at r27259 and commit of a patch by anthony jones to fix msvc (though...
[blender.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   Join Triangles
345
346   Tries to intelligently join triangles according 
347   to various settings and stuff.
348
349   */
350 BMOpDefine def_join_triangles= {
351         "join_triangles",
352         {{BMOP_OPSLOT_ELEMENT_BUF, "faces"}, //input geometry.
353          {BMOP_OPSLOT_ELEMENT_BUF, "faceout"}, //joined faces
354          {BMOP_OPSLOT_INT, "compare_sharp"},
355          {BMOP_OPSLOT_INT, "compare_uvs"},
356          {BMOP_OPSLOT_INT, "compare_vcols"},
357          {BMOP_OPSLOT_INT, "compare_materials"},
358          {BMOP_OPSLOT_FLT, "limit"},
359          {0, /*null-terminating sentinel*/}},
360         bmesh_jointriangles_exec,
361         0,
362 };
363
364 /*
365   Contextual Create
366
367   This is basically fkey, it creates
368   new faces from vertices, makes stuff from edge nets,
369   makes wire edges, etc.  It also dissolves
370   faces.
371   
372   Three verts become a triangle, four become a quad.  Two
373   become a wire edge.
374   */
375 BMOpDefine def_contextual_create= {
376         "contextual_create",
377         {{BMOP_OPSLOT_ELEMENT_BUF, "geom"}, //input geometry.
378          {BMOP_OPSLOT_ELEMENT_BUF, "faceout"}, //newly-made face(s)
379          {0, /*null-terminating sentinel*/}},
380         bmesh_contextual_create_exec,
381         0,
382 };
383
384 BMOpDefine def_edgenet_fill= {
385         "edgenet_fill",
386         {{BMOP_OPSLOT_ELEMENT_BUF, "edges"},
387          {BMOP_OPSLOT_ELEMENT_BUF, "faceout"},
388         {0, /*null-terminating sentinel*/}},
389         bmesh_edgenet_fill_exec,
390         0,
391 };
392
393 /*
394   Edgenet Prepare
395
396   Identifies several useful edge loop cases and modifies them so
397   they'll become a face when edgenet_fill is called.  The cases covered are:
398
399   * One single loop; an edge is added to connect the ends
400   * Two loops; two edges are added to connect the endpoints (based on the
401     shortest distance between each endpont).
402 */
403 BMOpDefine def_edgenet_prepare= {
404         "edgenet_prepare",
405         {{BMOP_OPSLOT_ELEMENT_BUF, "edges"}, //input edges
406          {BMOP_OPSLOT_ELEMENT_BUF, "edgeout"}, //new edges
407         {0, /*null-terminating sentinel*/}},
408         bmesh_edgenet_prepare,
409         0,
410 };
411
412 /*
413   Rotate
414
415   Rotate vertices around a center, using a 3x3 rotation
416   matrix.  Equivilent of the old rotateflag function.
417 */
418 BMOpDefine def_rotate = {
419         "rotate",
420         {{BMOP_OPSLOT_VEC, "cent"}, //center of rotation
421          {BMOP_OPSLOT_MAT, "mat"}, //matrix defining rotation
422         {BMOP_OPSLOT_ELEMENT_BUF, "verts"}, //input vertices
423         {0, /*null-terminating sentinel*/}},
424         bmesh_rotate_exec,
425         0,
426 };
427
428 /*
429   Translate
430
431   Translate vertices by an offset.  Equivelent of the
432   old translateflag function.
433 */
434 BMOpDefine def_translate= {
435         "translate",
436         {{BMOP_OPSLOT_VEC, "vec"}, //translation offset
437         {BMOP_OPSLOT_ELEMENT_BUF, "verts"}, //input vertices
438         {0, /*null-terminating sentinel*/}},
439         bmesh_translate_exec,
440         0,
441 };
442
443 /*
444   Scale
445
446   Scales vertices by an offset.
447 */
448 BMOpDefine def_scale= {
449         "scale",
450         {{BMOP_OPSLOT_VEC, "vec"}, //scale factor
451         {BMOP_OPSLOT_ELEMENT_BUF, "verts"}, //input vertices
452         {0, /*null-terminating sentinel*/}},
453         bmesh_scale_exec,
454         0,
455 };
456
457
458 /*
459   Transform
460
461   Transforms a set of vertices by a matrix.  Multiplies
462   the vertex coordinates with the matrix.
463 */
464 BMOpDefine def_transform = {
465         "transform",
466         {{BMOP_OPSLOT_MAT, "mat"}, //transform matrix
467         {BMOP_OPSLOT_ELEMENT_BUF, "verts"}, //input vertices
468         {0, /*null-terminating sentinel*/}},
469         bmesh_transform_exec,
470         0,
471 };
472
473 /*
474   Object Load BMesh
475
476   Loads a bmesh into an object/mesh.  This is a "private"
477   bmop.
478 */
479 BMOpDefine def_object_load_bmesh = {
480         "object_load_bmesh",
481         {{BMOP_OPSLOT_PNT, "scene"},
482         {BMOP_OPSLOT_PNT, "object"},
483         {0, /*null-terminating sentinel*/}},
484         object_load_bmesh_exec,
485         0,
486 };
487
488
489 /*
490   BMesh to Mesh
491
492   Converts a bmesh to a Mesh.  This is reserved for exiting editmode.
493 */
494 BMOpDefine def_bmesh_to_mesh = {
495         "bmesh_to_mesh",
496         {{BMOP_OPSLOT_PNT, "mesh"}, //pointer to a mesh structure to fill in
497          {BMOP_OPSLOT_PNT, "object"}, //pointer to an object structure
498          {BMOP_OPSLOT_INT, "notesselation"}, //don't calculate mfaces
499          {0, /*null-terminating sentinel*/}},
500         bmesh_to_mesh_exec,
501         0,
502 };
503
504 /*
505   Mesh to BMesh
506
507   Load the contents of a mesh into the bmesh.  this bmop is private, it's
508   reserved exclusively for entering editmode.
509 */
510 BMOpDefine def_mesh_to_bmesh = {
511         "mesh_to_bmesh",
512         {{BMOP_OPSLOT_PNT, "mesh"}, //pointer to a Mesh structure
513          {BMOP_OPSLOT_PNT, "object"}, //pointer to an Object structure
514          {0, /*null-terminating sentinel*/}},
515         mesh_to_bmesh_exec,
516         0
517 };
518
519 /*
520   Individual Face Extrude
521
522   Extrudes faces individually.
523 */
524 BMOpDefine def_extrude_indivface = {
525         "extrude_face_indiv",
526         {{BMOP_OPSLOT_ELEMENT_BUF, "faces"}, //input faces
527         {BMOP_OPSLOT_ELEMENT_BUF, "faceout"}, //output faces
528         {BMOP_OPSLOT_ELEMENT_BUF, "skirtout"}, //output skirt geometry, faces and edges
529         {0} /*null-terminating sentinel*/},
530         bmesh_extrude_face_indiv_exec,
531         0
532 };
533
534 /*
535   Extrude Only Edges
536
537   Extrudes Edges into faces, note that this is very simple, there's no fancy
538   winged extrusion.
539 */
540 BMOpDefine def_extrude_onlyedge = {
541         "extrude_edge_only",
542         {{BMOP_OPSLOT_ELEMENT_BUF, "edges"}, //input vertices
543         {BMOP_OPSLOT_ELEMENT_BUF, "geomout"}, //output geometry
544         {0} /*null-terminating sentinel*/},
545         bmesh_extrude_onlyedge_exec,
546         0
547 };
548
549 /*
550   Individual Vertex Extrude
551
552   Extrudes wire edges from vertices.
553 */
554 BMOpDefine def_extrudeverts_indiv = {
555         "extrude_vert_indiv",
556         {{BMOP_OPSLOT_ELEMENT_BUF, "verts"}, //input vertices
557         {BMOP_OPSLOT_ELEMENT_BUF, "edgeout"}, //output wire edges
558         {BMOP_OPSLOT_ELEMENT_BUF, "vertout"}, //output vertices
559         {0} /*null-terminating sentinel*/},
560         extrude_vert_indiv_exec,
561         0
562 };
563
564 #if 0
565 BMOpDefine def_makeprim = {
566         "makeprim",
567         {{BMOP_OPSLOT_INT, "type"},
568         {BMOP_OPSLOT_INT, "tot", /*rows/cols also applies to spheres*/
569         {BMOP_OPSLOT_INT, "seg",
570         {BMOP_OPSLOT_INT, "subdiv"},
571         {BMOP_OPSLOT_INT, "ext"},
572         {BMOP_OPSLOT_INT, "fill"},
573         {BMOP_OPSLOT_FLT, "dia"},
574         {BMOP_OPSLOT_FLT, "depth"},
575         {BMOP_OPSLOT_PNT, "mat"},
576         {BMOP_OPSLOT_ELEMENT_BUF, "geomout"}, //won't be implemented right away
577         {0}}
578         makeprim_exec,
579         0
580 };
581 #endif
582
583 BMOpDefine def_connectverts = {
584         "connectverts",
585         {{BMOP_OPSLOT_ELEMENT_BUF, "verts"},
586         {BMOP_OPSLOT_ELEMENT_BUF, "edgeout"},
587         {0} /*null-terminating sentinel*/},
588         connectverts_exec,
589         0
590 };
591
592 BMOpDefine def_extrudefaceregion = {
593         "extrudefaceregion",
594         {{BMOP_OPSLOT_ELEMENT_BUF, "edgefacein"},
595         {BMOP_OPSLOT_MAPPING, "exclude"},
596         {BMOP_OPSLOT_ELEMENT_BUF, "geomout"},
597         {0} /*null-terminating sentinel*/},
598         extrude_edge_context_exec,
599         0
600 };
601
602 BMOpDefine def_dissolvevertsop = {
603         "dissolveverts",
604         {{BMOP_OPSLOT_ELEMENT_BUF, "verts"},
605         {0} /*null-terminating sentinel*/},
606         dissolveverts_exec,
607         0
608 };
609
610 BMOpDefine def_dissolveedgessop = {
611         "dissolveedges",
612         {{BMOP_OPSLOT_ELEMENT_BUF, "edges"},
613         {BMOP_OPSLOT_ELEMENT_BUF, "regionout"},
614         {0} /*null-terminating sentinel*/},
615         dissolveedges_exec,
616         0
617 };
618
619 BMOpDefine def_dissolveedgeloopsop = {
620         "dissolveedgeloop",
621         {{BMOP_OPSLOT_ELEMENT_BUF, "edges"},
622         {BMOP_OPSLOT_ELEMENT_BUF, "regionout"},
623         {0} /*null-terminating sentinel*/},
624         dissolve_edgeloop_exec,
625         0
626 };
627
628 BMOpDefine def_dissolvefacesop = {
629         "dissolvefaces",
630         {{BMOP_OPSLOT_ELEMENT_BUF, "faces"},
631         {BMOP_OPSLOT_ELEMENT_BUF, "regionout"},
632         {0} /*null-terminating sentinel*/},
633         dissolvefaces_exec,
634         0
635 };
636
637
638 BMOpDefine def_triangop = {
639         "triangulate",
640         {{BMOP_OPSLOT_ELEMENT_BUF, "faces"},
641         {BMOP_OPSLOT_ELEMENT_BUF, "edgeout"},
642         {BMOP_OPSLOT_ELEMENT_BUF, "faceout"},
643         {BMOP_OPSLOT_MAPPING, "facemap"},
644         {0} /*null-terminating sentinel*/},
645         triangulate_exec,
646         0
647 };
648
649 BMOpDefine def_subdop = {
650         "esubd",
651         {{BMOP_OPSLOT_ELEMENT_BUF, "edges"},
652         {BMOP_OPSLOT_INT, "numcuts"},
653         {BMOP_OPSLOT_FLT, "smooth"},
654         {BMOP_OPSLOT_FLT, "fractal"},
655         {BMOP_OPSLOT_INT, "beauty"},
656         {BMOP_OPSLOT_MAPPING, "custompatterns"},
657         {BMOP_OPSLOT_MAPPING, "edgepercents"},
658         
659         /*these next three can have multiple types of elements in them.*/
660         {BMOP_OPSLOT_ELEMENT_BUF, "outinner"},
661         {BMOP_OPSLOT_ELEMENT_BUF, "outsplit"},
662         {BMOP_OPSLOT_ELEMENT_BUF, "geomout"}, /*contains all output geometry*/
663
664         {BMOP_OPSLOT_INT, "quadcornertype"}, //quad corner type, see bmesh_operators.h
665         {BMOP_OPSLOT_INT, "gridfill"}, //fill in fully-selected faces with a grid
666         {BMOP_OPSLOT_INT, "singleedge"}, //tesselate the case of one edge selected in a quad or triangle
667
668         {0} /*null-terminating sentinel*/,
669         },
670         esubdivide_exec,
671         0
672 };
673
674 BMOpDefine def_delop = {
675         "del",
676         {{BMOP_OPSLOT_ELEMENT_BUF, "geom"}, {BMOP_OPSLOT_INT, "context"},
677         {0} /*null-terminating sentinel*/},
678         delop_exec,
679         0
680 };
681
682 BMOpDefine def_dupeop = {
683         "dupe",
684         {{BMOP_OPSLOT_ELEMENT_BUF, "geom"},
685         {BMOP_OPSLOT_ELEMENT_BUF, "origout"},
686         {BMOP_OPSLOT_ELEMENT_BUF, "newout"},
687         /*facemap maps from source faces to dupe
688           faces, and from dupe faces to source faces.*/
689         {BMOP_OPSLOT_MAPPING, "facemap"},
690         {BMOP_OPSLOT_MAPPING, "boundarymap"},
691         {BMOP_OPSLOT_MAPPING, "isovertmap"},
692         {0} /*null-terminating sentinel*/},
693         dupeop_exec,
694         0
695 };
696
697 BMOpDefine def_splitop = {
698         "split",
699         {{BMOP_OPSLOT_ELEMENT_BUF, "geom"},
700         {BMOP_OPSLOT_ELEMENT_BUF, "geomout"},
701         {BMOP_OPSLOT_MAPPING, "boundarymap"},
702         {BMOP_OPSLOT_MAPPING, "isovertmap"},
703         {0} /*null-terminating sentinel*/},
704         splitop_exec,
705         0
706 };
707
708 /*
709   Similar faces search
710
711   Find similar faces (area/material/perimeter....).
712 */
713 BMOpDefine def_similarfaces = {
714         "similarfaces",
715         {{BMOP_OPSLOT_ELEMENT_BUF, "faces"}, /* input faces */
716          {BMOP_OPSLOT_ELEMENT_BUF, "faceout"}, /* output faces */
717          {BMOP_OPSLOT_INT, "type"},                     /* type of selection */
718          {BMOP_OPSLOT_FLT, "thresh"},           /* threshold of selection */
719          {0} /*null-terminating sentinel*/},
720         bmesh_similarfaces_exec,
721         0
722 };
723
724 /*
725   Similar edges search
726
727   Find similar edges (length, direction, edge, seam,....).
728 */
729 BMOpDefine def_similaredges = {
730         "similaredges",
731         {{BMOP_OPSLOT_ELEMENT_BUF, "edges"}, /* input edges */
732          {BMOP_OPSLOT_ELEMENT_BUF, "edgeout"}, /* output edges */
733          {BMOP_OPSLOT_INT, "type"},                     /* type of selection */
734          {BMOP_OPSLOT_FLT, "thresh"},           /* threshold of selection */
735          {0} /*null-terminating sentinel*/},
736         bmesh_similaredges_exec,
737         0
738 };
739
740 /*
741   Similar vertices search
742
743   Find similar vertices (normal, face, vertex group,....).
744 */
745 BMOpDefine def_similarverts = {
746         "similarverts",
747         {{BMOP_OPSLOT_ELEMENT_BUF, "verts"}, /* input vertices */
748          {BMOP_OPSLOT_ELEMENT_BUF, "vertout"}, /* output vertices */
749          {BMOP_OPSLOT_INT, "type"},                     /* type of selection */
750          {BMOP_OPSLOT_FLT, "thresh"},           /* threshold of selection */
751          {0} /*null-terminating sentinel*/},
752         bmesh_similarverts_exec,
753         0
754 };
755
756 /*
757 ** uv rotation
758 ** cycle the uvs
759 */
760 BMOpDefine def_meshrotateuvs = {
761         "meshrotateuvs",
762         {{BMOP_OPSLOT_ELEMENT_BUF, "faces"}, /* input faces */
763          {BMOP_OPSLOT_INT, "dir"},                      /* direction */
764          {0} /*null-terminating sentinel*/},
765         bmesh_rotateuvs_exec,
766         0
767 };
768
769 /*
770 ** uv reverse
771 ** reverse the uvs
772 */
773 BMOpDefine def_meshreverseuvs = {
774         "meshreverseuvs",
775         {{BMOP_OPSLOT_ELEMENT_BUF, "faces"}, /* input faces */
776          {0} /*null-terminating sentinel*/},
777         bmesh_reverseuvs_exec,
778         0
779 };
780
781 /*
782 ** color rotation
783 ** cycle the colors
784 */
785 BMOpDefine def_meshrotatecolors = {
786         "meshrotatecolors",
787         {{BMOP_OPSLOT_ELEMENT_BUF, "faces"}, /* input faces */
788          {BMOP_OPSLOT_INT, "dir"},                      /* direction */
789          {0} /*null-terminating sentinel*/},
790         bmesh_rotatecolors_exec,
791         0
792 };
793
794 /*
795 ** color reverse
796 ** reverse the colors
797 */
798 BMOpDefine def_meshreversecolors = {
799         "meshreversecolors",
800         {{BMOP_OPSLOT_ELEMENT_BUF, "faces"}, /* input faces */
801          {0} /*null-terminating sentinel*/},
802         bmesh_reversecolors_exec,
803         0
804 };
805
806 /*
807   Similar vertices search
808
809   Find similar vertices (normal, face, vertex group,....).
810 */
811 BMOpDefine def_vertexshortestpath = {
812         "vertexshortestpath",
813         {{BMOP_OPSLOT_ELEMENT_BUF, "startv"}, /* start vertex */
814          {BMOP_OPSLOT_ELEMENT_BUF, "endv"}, /* end vertex */
815          {BMOP_OPSLOT_ELEMENT_BUF, "vertout"}, /* output vertices */
816          {BMOP_OPSLOT_INT, "type"},                     /* type of selection */
817          {0} /*null-terminating sentinel*/},
818         bmesh_vertexshortestpath_exec,
819         0
820 };
821
822 /*
823   Edge Split
824
825   Disconnects faces along input edges.
826  */
827 BMOpDefine def_edgesplit = {
828         "edgesplit",
829         {{BMOP_OPSLOT_ELEMENT_BUF, "edges"}, /* input edges */
830          {BMOP_OPSLOT_ELEMENT_BUF, "edgeout1"}, /* old output disconnected edges */
831          {BMOP_OPSLOT_ELEMENT_BUF, "edgeout2"}, /* new output disconnected edges */
832          {0} /*null-terminating sentinel*/},
833         bmesh_edgesplitop_exec,
834         0
835 };
836
837 /*
838   Create Grid
839
840   Creates a grid with a variable number of subdivisions
841 */
842 BMOpDefine def_create_grid = {
843         "create_grid",
844         {{BMOP_OPSLOT_ELEMENT_BUF, "vertout"}, //output verts
845          {BMOP_OPSLOT_INT,         "xsegments"}, //number of x segments
846          {BMOP_OPSLOT_INT,         "ysegments"}, //number of y segments
847          {BMOP_OPSLOT_FLT,         "size"}, //size of the grid
848          {BMOP_OPSLOT_MAT,         "mat"}, //matrix to multiply the new geometry with
849          {0, /*null-terminating sentinel*/}},
850         bmesh_create_grid_exec,
851         0,
852 };
853
854 /*
855   Create UV Sphere
856
857   Creates a grid with a variable number of subdivisions
858 */
859 BMOpDefine def_create_uvsphere = {
860         "create_uvsphere",
861         {{BMOP_OPSLOT_ELEMENT_BUF, "vertout"}, //output verts
862          {BMOP_OPSLOT_INT,         "segments"}, //number of u segments
863          {BMOP_OPSLOT_INT,         "revolutions"}, //number of v segment
864          {BMOP_OPSLOT_FLT,         "diameter"}, //diameter
865          {BMOP_OPSLOT_MAT,         "mat"}, //matrix to multiply the new geometry with--
866          {0, /*null-terminating sentinel*/}},
867         bmesh_create_uvsphere_exec,
868         0,
869 };
870
871 /*
872   Create Ico Sphere
873
874   Creates a grid with a variable number of subdivisions
875 */
876 BMOpDefine def_create_icosphere = {
877         "create_icosphere",
878         {{BMOP_OPSLOT_ELEMENT_BUF, "vertout"}, //output verts
879          {BMOP_OPSLOT_INT,         "subdivisions"}, //how many times to recursively subdivide the sphere
880          {BMOP_OPSLOT_FLT,       "diameter"}, //diameter
881          {BMOP_OPSLOT_MAT, "mat"}, //matrix to multiply the new geometry with
882          {0, /*null-terminating sentinel*/}},
883         bmesh_create_icosphere_exec,
884         0,
885 };
886
887 /*
888   Create Suzanne
889
890   Creates a monkey.  Be wary.
891 */
892 BMOpDefine def_create_monkey = {
893         "create_monkey",
894         {{BMOP_OPSLOT_ELEMENT_BUF, "vertout"}, //output verts
895          {BMOP_OPSLOT_MAT, "mat"}, //matrix to multiply the new geometry with--
896          {0, /*null-terminating sentinel*/}},
897         bmesh_create_monkey_exec,
898         0,
899 };
900
901 /*
902   Create Cone
903
904   Creates a cone with variable depth at both ends
905 */
906 BMOpDefine def_create_cone = {
907         "create_cone",
908         {{BMOP_OPSLOT_ELEMENT_BUF, "vertout"}, //output verts
909          {BMOP_OPSLOT_INT, "cap_ends"}, //wheter or not to fill in the ends with faces
910          {BMOP_OPSLOT_INT, "segments"},
911          {BMOP_OPSLOT_FLT, "diameter1"}, //diameter of one end
912          {BMOP_OPSLOT_FLT, "diameter2"}, //diameter of the opposite
913          {BMOP_OPSLOT_FLT, "depth"}, //distance between ends
914          {BMOP_OPSLOT_MAT, "mat"}, //matrix to multiply the new geometry with--
915          {0, /*null-terminating sentinel*/}},
916         bmesh_create_cone_exec,
917         0,
918 };
919
920 /*
921   Create Cone
922
923   Creates a cone with variable depth at both ends
924 */
925 BMOpDefine def_create_cube = {
926         "create_cube",
927         {{BMOP_OPSLOT_ELEMENT_BUF, "vertout"}, //output verts
928          {BMOP_OPSLOT_FLT, "size"}, //size of the cube
929          {BMOP_OPSLOT_MAT, "mat"}, //matrix to multiply the new geometry with--
930          {0, /*null-terminating sentinel*/}},
931         bmesh_create_cube_exec,
932         0,
933 };
934
935 BMOpDefine *opdefines[] = {
936         &def_splitop,
937         &def_dupeop,
938         &def_delop,
939         &def_subdop,
940         &def_triangop,
941         &def_dissolvefacesop,
942         &def_dissolveedgessop,
943         &def_dissolveedgeloopsop,
944         &def_dissolvevertsop,
945         &def_extrudefaceregion,
946         &def_connectverts,
947         //&def_makeprim,
948         &def_extrudeverts_indiv,
949         &def_mesh_to_bmesh,
950         &def_object_load_bmesh,
951         &def_transform,
952         &def_translate,
953         &def_rotate,
954         &def_edgenet_fill,
955         &def_contextual_create,
956         &def_makevert,
957         &def_weldverts,
958         &def_removedoubles,
959         &def_finddoubles,
960         &def_mirror,
961         &def_edgebisect,
962         &def_reversefaces,
963         &def_edgerotate,
964         &def_regionextend,
965         &def_righthandfaces,
966         &def_vertexsmooth,
967         &def_extrude_onlyedge,
968         &def_extrude_indivface,
969         &def_collapse_uvs,
970         &def_pointmerge,
971         &def_collapse,
972         &def_similarfaces,
973         &def_similaredges,
974         &def_similarverts,
975         &def_pointmerge_facedata,
976         &def_vert_average_facedata,
977         &def_meshrotateuvs,
978         &def_bmesh_to_mesh,
979         &def_meshreverseuvs,
980         &def_edgenet_prepare,
981         &def_meshrotatecolors,
982         &def_meshreversecolors,
983         &def_vertexshortestpath,
984         &def_scale,
985         &def_edgesplit,
986         &def_automerge,
987         &def_create_uvsphere,
988         &def_create_grid,
989         &def_create_icosphere,
990         &def_create_monkey,
991         &def_create_cone,
992         &def_create_cube,
993         &def_join_triangles,
994 };
995
996 int bmesh_total_ops = (sizeof(opdefines) / sizeof(void*));