select more/less properly uses bmops now, and also made a little start on documenting...
[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
67 /*
68   Region Extend
69   
70   used to implement the select more/less tools.
71   this puts some geometry surrounding regions of
72   geometry in geom into geomout.
73   
74   if usefaces is 0 then geomout spits out verts and edges, 
75   otherwise it spits out faces.
76   */
77 BMOpDefine def_regionextend = {
78         "regionextend",
79         {{BMOP_OPSLOT_ELEMENT_BUF, "geom"}, //input geometry
80          {BMOP_OPSLOT_ELEMENT_BUF, "geomout"}, //output slot, computed boundary geometry.
81          {BMOP_OPSLOT_INT, "constrict"}, //find boundary inside the regions, not outside.
82          {BMOP_OPSLOT_INT, "usefaces"}, //extend from faces instead of edges
83         {0} /*null-terminating sentinel*/,
84         },
85         bmesh_regionextend_exec,
86         0
87 };
88
89 /*
90   Edge Rotate
91
92   Rotates edges topologically.  Also known as "spin edge" to some people.
93   Simple example: [/] becomes [|] then [\].
94 */
95 BMOpDefine def_edgerotate = {
96         "edgerotate",
97         {{BMOP_OPSLOT_ELEMENT_BUF, "edges"}, //input edges
98          {BMOP_OPSLOT_ELEMENT_BUF, "edgeout"}, //newly spun edges
99          {BMOP_OPSLOT_INT, "ccw"}, //rotate edge counter-clockwise if true, othewise clockwise
100         {0} /*null-terminating sentinel*/,
101         },
102         bmesh_edgerotate_exec,
103         0
104 };
105
106 /*
107   Reverse Faces
108
109   Reverses the winding (vertex order) of faces.  This has the effect of
110   flipping the normal.
111 */
112 BMOpDefine def_reversefaces = {
113         "reversefaces",
114         {{BMOP_OPSLOT_ELEMENT_BUF, "faces"}, //input faces
115         {0} /*null-terminating sentinel*/,
116         },
117         bmesh_reversefaces_exec,
118         0
119 };
120
121 /*
122   Edge Split
123
124   Splits input edges (but doesn't do anything else).
125 */
126 BMOpDefine def_edgesplit = {
127         "edgesplit",
128         {{BMOP_OPSLOT_ELEMENT_BUF, "edges"}, //input edges
129         {BMOP_OPSLOT_INT, "numcuts"}, //number of cuts
130         {BMOP_OPSLOT_ELEMENT_BUF, "outsplit"}, //newly created vertices and edges
131         {0} /*null-terminating sentinel*/,
132         },
133         esplit_exec,
134         0
135 };
136
137 /*
138   Mirror
139
140   Mirrors geometry along an axis.  The resulting geometry is welded on using
141   mergedist.  Pairs of original/mirrored vertices are welded using the mergedist
142   parameter (which defines the minimum distance for welding to happen).
143 */
144
145 BMOpDefine def_mirror = {
146         "mirror",
147         {{BMOP_OPSLOT_ELEMENT_BUF, "geom"}, //input geometry
148          {BMOP_OPSLOT_MAT, "mat"}, //matrix defining the mirror transformation
149          {BMOP_OPSLOT_FLT, "mergedist"}, //maximum distance for merging.  does no merging if 0.
150          {BMOP_OPSLOT_ELEMENT_BUF, "newout"}, //output geometry, mirrored
151          {BMOP_OPSLOT_INT,         "axis"}, //the axis to use, 0, 1, or 2 for x, y, z
152          {BMOP_OPSLOT_INT,         "mirror_u"}, //mirror UVs across the u axis
153          {BMOP_OPSLOT_INT,         "mirror_v"}, //mirror UVs across the v axis
154          {0, /*null-terminating sentinel*/}},
155         bmesh_mirror_exec,
156         0,
157 };
158
159 BMOpDefine def_finddoubles = {
160         "finddoubles",
161         /*maps welded vertices to verts they should weld to.*/
162         {{BMOP_OPSLOT_ELEMENT_BUF, "verts"},
163          //list of verts to keep
164          {BMOP_OPSLOT_ELEMENT_BUF, "keepverts"},
165          {BMOP_OPSLOT_FLT,         "dist"},
166          {BMOP_OPSLOT_MAPPING, "targetmapout"},
167          {0, /*null-terminating sentinel*/}},
168         bmesh_finddoubles_exec,
169         0,
170 };
171
172 BMOpDefine def_removedoubles = {
173         "removedoubles",
174         /*maps welded vertices to verts they should weld to.*/
175         {{BMOP_OPSLOT_ELEMENT_BUF, "verts"},
176          {BMOP_OPSLOT_FLT,         "dist"},
177          {0, /*null-terminating sentinel*/}},
178         bmesh_removedoubles_exec,
179         0,
180 };
181
182 BMOpDefine def_weldverts = {
183         "weldverts",
184         /*maps welded vertices to verts they should weld to.*/
185         {{BMOP_OPSLOT_MAPPING, "targetmap"},
186          {0, /*null-terminating sentinel*/}},
187         bmesh_weldverts_exec,
188         0,
189 };
190
191 BMOpDefine def_makevert = {
192         "makevert",
193         {{BMOP_OPSLOT_VEC, "co"},
194         {BMOP_OPSLOT_ELEMENT_BUF, "newvertout"},
195         {0, /*null-terminating sentinel*/}},
196         bmesh_makevert_exec,
197         0,
198 };
199
200 /*contextual_create is fkey, it creates
201   new faces, makes stuff from edge nets,
202   makes wire edges, etc.  it also dissolves
203   faces.*/
204 BMOpDefine def_contextual_create= {
205         "contextual_create",
206         {{BMOP_OPSLOT_ELEMENT_BUF, "geom"},
207          {BMOP_OPSLOT_ELEMENT_BUF, "faceout"},
208          {0, /*null-terminating sentinel*/}},
209         bmesh_contextual_create_exec,
210         0,
211 };
212
213 BMOpDefine def_edgenet_fill= {
214         "edgenet_fill",
215         {{BMOP_OPSLOT_ELEMENT_BUF, "edges"},
216          {BMOP_OPSLOT_ELEMENT_BUF, "faceout"},
217         {0, /*null-terminating sentinel*/}},
218         bmesh_edgenet_fill_exec,
219         0,
220 };
221
222 BMOpDefine def_rotate = {
223         "rotate",
224         {{BMOP_OPSLOT_VEC, "cent"},
225          {BMOP_OPSLOT_MAT, "mat"},
226         {BMOP_OPSLOT_ELEMENT_BUF, "verts"},
227         {0, /*null-terminating sentinel*/}},
228         bmesh_rotate_exec,
229         0,
230 };
231
232 BMOpDefine def_translate= {
233         "translate",
234         {{BMOP_OPSLOT_VEC, "vec"},
235         {BMOP_OPSLOT_ELEMENT_BUF, "verts"},
236         {0, /*null-terminating sentinel*/}},
237         bmesh_translate_exec,
238         0,
239 };
240
241
242 /*applies a transform to vertices*/
243 BMOpDefine def_transform = {
244         "transform",
245         {{BMOP_OPSLOT_MAT, "mat"},
246         {BMOP_OPSLOT_ELEMENT_BUF, "verts"},
247         {0, /*null-terminating sentinel*/}},
248         bmesh_transform_exec,
249         0,
250 };
251
252 /*loads a bmesh into an object*/
253 BMOpDefine def_object_load_bmesh = {
254         "object_load_bmesh",
255         {{BMOP_OPSLOT_PNT, "scene"},
256         {BMOP_OPSLOT_PNT, "object"},
257         {0, /*null-terminating sentinel*/}},
258         bmesh_to_mesh_exec,
259         0,
260 };
261
262
263 BMOpDefine def_mesh_to_bmesh = {
264         "mesh_to_bmesh",
265         {{BMOP_OPSLOT_PNT, "mesh"},
266          {0, /*null-terminating sentinel*/}},
267         mesh_to_bmesh_exec,
268         0
269 };
270
271 BMOpDefine def_extrudeverts_indiv = {
272         "extrude_vert_indiv",
273         {{BMOP_OPSLOT_ELEMENT_BUF, "verts"},
274         {BMOP_OPSLOT_ELEMENT_BUF, "edgeout"},
275         {BMOP_OPSLOT_ELEMENT_BUF, "vertout"},
276         {0} /*null-terminating sentinel*/},
277         extrude_vert_indiv_exec,
278         0
279 };
280
281 #if 0
282 BMOpDefine def_makeprim = {
283         "makeprim",
284         {{BMOP_OPSLOT_INT, "type"},
285         {BMOP_OPSLOT_INT, "tot", /*rows/cols also applies to spheres*/
286         {BMOP_OPSLOT_INT, "seg",
287         {BMOP_OPSLOT_INT, "subdiv"},
288         {BMOP_OPSLOT_INT, "ext"},
289         {BMOP_OPSLOT_INT, "fill"},
290         {BMOP_OPSLOT_FLT, "dia"},
291         {BMOP_OPSLOT_FLT, "depth"},
292         {BMOP_OPSLOT_PNT, "mat"},
293         {BMOP_OPSLOT_ELEMENT_BUF, "geomout"}, //won't be implemented right away
294         {0}}
295         makeprim_exec,
296         0
297 };
298 #endif
299
300 BMOpDefine def_connectverts = {
301         "connectverts",
302         {{BMOP_OPSLOT_ELEMENT_BUF, "verts"},
303         {BMOP_OPSLOT_ELEMENT_BUF, "edgeout"},
304         {0} /*null-terminating sentinel*/},
305         connectverts_exec,
306         0
307 };
308
309 BMOpDefine def_extrudefaceregion = {
310         "extrudefaceregion",
311         {{BMOP_OPSLOT_ELEMENT_BUF, "edgefacein"},
312         {BMOP_OPSLOT_MAPPING, "exclude"},
313         {BMOP_OPSLOT_ELEMENT_BUF, "geomout"},
314         {0} /*null-terminating sentinel*/},
315         extrude_edge_context_exec,
316         0
317 };
318
319 BMOpDefine def_makefgonsop = {
320         "makefgon",
321         {{BMOP_OPSLOT_INT, "trifan"}, /*use triangle fans instead of 
322                                         real interpolation*/
323          {0} /*null-terminating sentinel*/},
324         bmesh_make_fgons_exec,
325         0
326 };
327
328 BMOpDefine def_dissolvevertsop = {
329         "dissolveverts",
330         {{BMOP_OPSLOT_ELEMENT_BUF, "verts"},
331         {0} /*null-terminating sentinel*/},
332         dissolveverts_exec,
333         0
334 };
335
336 BMOpDefine def_dissolveedgessop = {
337         "dissolveedges",
338         {{BMOP_OPSLOT_ELEMENT_BUF, "edges"},
339         {BMOP_OPSLOT_ELEMENT_BUF, "regionout"},
340         {0} /*null-terminating sentinel*/},
341         dissolveedges_exec,
342         0
343 };
344
345 BMOpDefine def_dissolveedgeloopsop = {
346         "dissolveedgeloop",
347         {{BMOP_OPSLOT_ELEMENT_BUF, "edges"},
348         {BMOP_OPSLOT_ELEMENT_BUF, "regionout"},
349         {0} /*null-terminating sentinel*/},
350         dissolve_edgeloop_exec,
351         0
352 };
353
354 BMOpDefine def_dissolvefacesop = {
355         "dissolvefaces",
356         {{BMOP_OPSLOT_ELEMENT_BUF, "faces"},
357         {BMOP_OPSLOT_ELEMENT_BUF, "regionout"},
358         {0} /*null-terminating sentinel*/},
359         dissolvefaces_exec,
360         0
361 };
362
363
364 BMOpDefine def_triangop = {
365         "triangulate",
366         {{BMOP_OPSLOT_ELEMENT_BUF, "faces"},
367         {BMOP_OPSLOT_ELEMENT_BUF, "edgeout"},
368         {BMOP_OPSLOT_ELEMENT_BUF, "faceout"},
369         {BMOP_OPSLOT_MAPPING, "facemap"},
370         {0} /*null-terminating sentinel*/},
371         triangulate_exec,
372         0
373 };
374
375 BMOpDefine def_subdop = {
376         "esubd",
377         {{BMOP_OPSLOT_ELEMENT_BUF, "edges"},
378         {BMOP_OPSLOT_INT, "numcuts"},
379         {BMOP_OPSLOT_FLT, "smooth"},
380         {BMOP_OPSLOT_FLT, "fractal"},
381         {BMOP_OPSLOT_INT, "beauty"},
382         {BMOP_OPSLOT_MAPPING, "custompatterns"},
383         {BMOP_OPSLOT_MAPPING, "edgepercents"},
384         
385         /*these next two can have multiple types of elements in them.*/
386         {BMOP_OPSLOT_ELEMENT_BUF, "outinner"},
387         {BMOP_OPSLOT_ELEMENT_BUF, "outsplit"},
388         {0} /*null-terminating sentinel*/,
389         },
390         esubdivide_exec,
391         0
392 };
393
394 BMOpDefine def_edit2bmesh = {
395         "editmesh_to_bmesh",
396         {{BMOP_OPSLOT_PNT, "em"}, {BMOP_OPSLOT_MAPPING, "map"},
397         {0} /*null-terminating sentinel*/},
398         edit2bmesh_exec,
399         0
400 };
401
402 BMOpDefine def_bmesh2edit = {
403         "bmesh_to_editmesh",
404         {{BMOP_OPSLOT_PNT, "emout"},
405         {0} /*null-terminating sentinel*/},
406         bmesh2edit_exec,
407         0
408 };
409
410 BMOpDefine def_delop = {
411         "del",
412         {{BMOP_OPSLOT_ELEMENT_BUF, "geom"}, {BMOP_OPSLOT_INT, "context"},
413         {0} /*null-terminating sentinel*/},
414         delop_exec,
415         0
416 };
417
418 BMOpDefine def_dupeop = {
419         "dupe",
420         {{BMOP_OPSLOT_ELEMENT_BUF, "geom"},
421         {BMOP_OPSLOT_ELEMENT_BUF, "origout"},
422         {BMOP_OPSLOT_ELEMENT_BUF, "newout"},
423         /*facemap maps from source faces to dupe
424           faces, and from dupe faces to source faces.*/
425         {BMOP_OPSLOT_MAPPING, "facemap"},
426         {BMOP_OPSLOT_MAPPING, "boundarymap"},
427         {BMOP_OPSLOT_MAPPING, "isovertmap"},
428         {0} /*null-terminating sentinel*/},
429         dupeop_exec,
430         0
431 };
432
433 BMOpDefine def_splitop = {
434         "split",
435         {{BMOP_OPSLOT_ELEMENT_BUF, "geom"},
436         {BMOP_OPSLOT_ELEMENT_BUF, "geomout"},
437         {BMOP_OPSLOT_MAPPING, "boundarymap"},
438         {BMOP_OPSLOT_MAPPING, "isovertmap"},
439         {0} /*null-terminating sentinel*/},
440         splitop_exec,
441         0
442 };
443
444 BMOpDefine *opdefines[] = {
445         &def_splitop,
446         &def_dupeop,
447         &def_delop,
448         &def_edit2bmesh,
449         &def_bmesh2edit,
450         &def_subdop,
451         &def_triangop,
452         &def_dissolvefacesop,
453         &def_dissolveedgessop,
454         &def_dissolveedgeloopsop,
455         &def_dissolvevertsop,
456         &def_makefgonsop,
457         &def_extrudefaceregion,
458         &def_connectverts,
459         //&def_makeprim,
460         &def_extrudeverts_indiv,
461         &def_mesh_to_bmesh,
462         &def_object_load_bmesh,
463         &def_transform,
464         &def_translate,
465         &def_rotate,
466         &def_edgenet_fill,
467         &def_contextual_create,
468         &def_makevert,
469         &def_weldverts,
470         &def_removedoubles,
471         &def_finddoubles,
472         &def_mirror,
473         &def_edgesplit,
474         &def_reversefaces,
475         &def_edgerotate,
476         &def_regionextend,
477 };
478
479 int bmesh_total_ops = (sizeof(opdefines) / sizeof(void*));