2 * ***** BEGIN GPL LICENSE BLOCK *****
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * Contributor(s): Joseph Eagar, Geoffrey Bantle, Campbell Barton
20 * ***** END GPL LICENSE BLOCK *****
23 /** \file blender/bmesh/intern/bmesh_opdefines.c
26 * BMesh operator definitions.
28 * This file defines (and documents) all bmesh operators (bmops).
30 * Do not rename any operator or slot names! otherwise you must go
31 * through the code and find all references to them!
33 * A word on slot names:
35 * For geometry input slots, the following are valid names:
45 * The basic rules are, for single-type geometry slots, use the plural of the
46 * type name (e.g. edges). for double-type slots, use the two type names plus
47 * "in" (e.g. edgefacein). for three-type slots, use geom.
49 * for output slots, for single-type geometry slots, use the type name plus "out",
50 * (e.g. vertout), for double-type slots, use the two type names plus "out",
51 * (e.g. vertfaceout), for three-type slots, use geom. note that you can also
52 * use more esohteric names (e.g. skirtout) so long as the comment next to the
53 * slot definition tells you what types of elements are in it.
57 #include "BLI_utildefines.h"
60 #include "intern/bmesh_private.h"
62 /* ok, I'm going to write a little docgen script. so all
63 * bmop comments must conform to the following template/rules:
65 * template (py quotes used because nested comments don't work
66 * on all C compilers):
71 * paragraph1, Extends bleh bleh bleh.
79 * so the first line is the "title" of the bmop.
80 * subsequent line blocks separated by blank lines
81 * are paragraphs. individual descriptions of slots
82 * would be extracted from comments
85 * {BMO_OP_SLOT_ELEMENT_BUF, "geomout"}, //output slot, boundary region
87 * the doc generator would automatically detect the presence of "output slot"
88 * and flag the slot as an output. the same happens for "input slot". also
89 * note that "edges", "faces", "verts", "loops", and "geometry" are valid
90 * substitutions for "slot".
92 * note that slots default to being input slots.
98 * Smooths vertices by using a basic vertex averaging scheme.
100 static BMOpDefine bmo_vertexsmooth_def = {
102 {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, //input vertices
103 {BMO_OP_SLOT_BOOL, "mirror_clip_x"}, //set vertices close to the x axis before the operation to 0
104 {BMO_OP_SLOT_BOOL, "mirror_clip_y"}, //set vertices close to the y axis before the operation to 0
105 {BMO_OP_SLOT_BOOL, "mirror_clip_z"}, //set vertices close to the z axis before the operation to 0
106 {BMO_OP_SLOT_FLT, "clipdist"}, //clipping threshod for the above three slots
107 {0} /* null-terminating sentinel */,
109 bmo_vertexsmooth_exec,
116 * Computes an "outside" normal for the specified input faces.
119 static BMOpDefine bmo_righthandfaces_def = {
121 {{BMO_OP_SLOT_ELEMENT_BUF, "faces"},
122 {BMO_OP_SLOT_BOOL, "do_flip"}, //internal flag, used by bmesh_rationalize_normals
123 {0} /* null-terminating sentinel */,
125 bmo_righthandfaces_exec,
126 BMO_OP_FLAG_UNTAN_MULTIRES,
132 * used to implement the select more/less tools.
133 * this puts some geometry surrounding regions of
134 * geometry in geom into geomout.
136 * if usefaces is 0 then geomout spits out verts and edges,
137 * otherwise it spits out faces.
139 static BMOpDefine bmo_regionextend_def = {
141 {{BMO_OP_SLOT_ELEMENT_BUF, "geom"}, //input geometry
142 {BMO_OP_SLOT_ELEMENT_BUF, "geomout"}, //output slot, computed boundary geometry.
143 {BMO_OP_SLOT_BOOL, "constrict"}, //find boundary inside the regions, not outside.
144 {BMO_OP_SLOT_BOOL, "use_faces"}, //extend from faces instead of edges
145 {0} /* null-terminating sentinel */,
147 bmo_regionextend_exec,
154 * Rotates edges topologically. Also known as "spin edge" to some people.
155 * Simple example: [/] becomes [|] then [\].
157 static BMOpDefine bmo_edgerotate_def = {
159 {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, //input edges
160 {BMO_OP_SLOT_ELEMENT_BUF, "edgeout"}, //newly spun edges
161 {BMO_OP_SLOT_BOOL, "ccw"}, //rotate edge counter-clockwise if true, othewise clockwise
162 {0} /* null-terminating sentinel */,
165 BMO_OP_FLAG_UNTAN_MULTIRES
171 * Reverses the winding (vertex order) of faces. This has the effect of
172 * flipping the normal.
174 static BMOpDefine bmo_reversefaces_def = {
176 {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, //input faces
177 {0} /* null-terminating sentinel */,
179 bmo_reversefaces_exec,
180 BMO_OP_FLAG_UNTAN_MULTIRES,
186 * Splits input edges (but doesn't do anything else).
187 * This creates a 2-valence vert.
189 static BMOpDefine bmo_edgebisect_def = {
191 {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, //input edges
192 {BMO_OP_SLOT_INT, "numcuts"}, //number of cuts
193 {BMO_OP_SLOT_ELEMENT_BUF, "outsplit"}, //newly created vertices and edges
194 {0} /* null-terminating sentinel */,
197 BMO_OP_FLAG_UNTAN_MULTIRES
203 * Mirrors geometry along an axis. The resulting geometry is welded on using
204 * mergedist. Pairs of original/mirrored vertices are welded using the mergedist
205 * parameter (which defines the minimum distance for welding to happen).
208 static BMOpDefine bmo_mirror_def = {
210 {{BMO_OP_SLOT_ELEMENT_BUF, "geom"}, //input geometry
211 {BMO_OP_SLOT_MAT, "mat"}, //matrix defining the mirror transformation
212 {BMO_OP_SLOT_FLT, "mergedist"}, //maximum distance for merging. does no merging if 0.
213 {BMO_OP_SLOT_ELEMENT_BUF, "newout"}, //output geometry, mirrored
214 {BMO_OP_SLOT_INT, "axis"}, //the axis to use, 0, 1, or 2 for x, y, z
215 {BMO_OP_SLOT_BOOL, "mirror_u"}, //mirror UVs across the u axis
216 {BMO_OP_SLOT_BOOL, "mirror_v"}, //mirror UVs across the v axis
217 {0, /* null-terminating sentinel */}},
225 * Takes input verts and find vertices they should weld to. Outputs a
226 * mapping slot suitable for use with the weld verts bmop.
228 * If keepverts is used, vertices outside that set can only be merged
229 * with vertices in that set.
231 static BMOpDefine bmo_finddoubles_def = {
233 {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, //input vertices
234 {BMO_OP_SLOT_ELEMENT_BUF, "keepverts"}, //list of verts to keep
235 {BMO_OP_SLOT_FLT, "dist"}, //minimum distance
236 {BMO_OP_SLOT_MAPPING, "targetmapout"},
237 {0, /* null-terminating sentinel */}},
238 bmo_finddoubles_exec,
245 * Finds groups of vertices closer then dist and merges them together,
246 * using the weld verts bmop.
248 static BMOpDefine bmo_removedoubles_def = {
250 {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, //input verts
251 {BMO_OP_SLOT_FLT, "dist"}, //minimum distance
252 {0, /* null-terminating sentinel */}},
253 bmo_removedoubles_exec,
254 BMO_OP_FLAG_UNTAN_MULTIRES,
260 * Finds groups of vertices closer then dist and merges them together,
261 * using the weld verts bmop. The merges must go from a vert not in
262 * verts to one in verts.
264 static BMOpDefine bmo_automerge_def = {
266 {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, //input verts
267 {BMO_OP_SLOT_FLT, "dist"}, //minimum distance
268 {0, /* null-terminating sentinel */}},
270 BMO_OP_FLAG_UNTAN_MULTIRES,
276 * Collapses connected vertices
278 static BMOpDefine bmo_collapse_def = {
280 {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edge */
281 {0, /* null-terminating sentinel */}},
283 BMO_OP_FLAG_UNTAN_MULTIRES,
288 * Facedata point Merge
290 * Merge uv/vcols at a specific vertex.
292 static BMOpDefine bmo_pointmerge_facedata_def = {
293 "pointmerge_facedata",
294 {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertice */
295 {BMO_OP_SLOT_ELEMENT_BUF, "snapv"}, /* snap verte */
296 {0, /* null-terminating sentinel */}},
297 bmo_pointmerge_facedata_exec,
302 * Average Vertices Facevert Data
304 * Merge uv/vcols associated with the input vertices at
305 * the bounding box center. (I know, it's not averaging but
306 * the vert_snap_to_bb_center is just too long).
308 static BMOpDefine bmo_vert_average_facedata_def = {
309 "vert_average_facedata",
310 {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertice */
311 {0, /* null-terminating sentinel */}},
312 bmo_vert_average_facedata_exec,
319 * Merge verts together at a point.
321 static BMOpDefine bmo_pointmerge_def = {
323 {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertice */
324 {BMO_OP_SLOT_VEC, "mergeco"},
325 {0, /* null-terminating sentinel */}},
327 BMO_OP_FLAG_UNTAN_MULTIRES,
331 * Collapse Connected UVs
333 * Collapses connected UV vertices.
335 static BMOpDefine bmo_collapse_uvs_def = {
337 {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edge */
338 {0, /* null-terminating sentinel */}},
339 bmo_collapse_uvs_exec,
346 * Welds verts together (kindof like remove doubles, merge, etc, all of which
347 * use or will use this bmop). You pass in mappings from vertices to the vertices
350 static BMOpDefine bmo_weldverts_def = {
352 {{BMO_OP_SLOT_MAPPING, "targetmap"}, /* maps welded vertices to verts they should weld to */
353 {0, /* null-terminating sentinel */}},
355 BMO_OP_FLAG_UNTAN_MULTIRES,
361 * Creates a single vertex; this bmop was necessary
362 * for click-create-vertex.
364 static BMOpDefine bmo_makevert_def = {
366 {{BMO_OP_SLOT_VEC, "co"}, //the coordinate of the new vert
367 {BMO_OP_SLOT_ELEMENT_BUF, "newvertout"}, //the new vert
368 {0, /* null-terminating sentinel */}},
376 * Tries to intelligently join triangles according
377 * to various settings and stuff.
379 static BMOpDefine bmo_join_triangles_def = {
381 {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, //input geometry.
382 {BMO_OP_SLOT_ELEMENT_BUF, "faceout"}, //joined faces
383 {BMO_OP_SLOT_BOOL, "cmp_sharp"},
384 {BMO_OP_SLOT_BOOL, "cmp_uvs"},
385 {BMO_OP_SLOT_BOOL, "cmp_vcols"},
386 {BMO_OP_SLOT_BOOL, "cmp_materials"},
387 {BMO_OP_SLOT_FLT, "limit"},
388 {0, /* null-terminating sentinel */}},
389 bmo_join_triangles_exec,
390 BMO_OP_FLAG_UNTAN_MULTIRES,
396 * This is basically fkey, it creates
397 * new faces from vertices, makes stuff from edge nets,
398 * makes wire edges, etc. It also dissolves
401 * Three verts become a triangle, four become a quad. Two
402 * become a wire edge.
404 static BMOpDefine bmo_contextual_create_def = {
406 {{BMO_OP_SLOT_ELEMENT_BUF, "geom"}, //input geometry.
407 {BMO_OP_SLOT_ELEMENT_BUF, "faceout"}, /* newly-made face(s) */
408 {BMO_OP_SLOT_INT, "mat_nr"}, /* material to use */
409 {BMO_OP_SLOT_BOOL, "use_smooth"}, /* material to use */
410 {0, /* null-terminating sentinel */}},
411 bmo_contextual_create_exec,
412 BMO_OP_FLAG_UNTAN_MULTIRES,
416 * Bridge edge loops with faces
418 static BMOpDefine bmo_bridge_loops_def = {
420 {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edge */
421 {BMO_OP_SLOT_ELEMENT_BUF, "faceout"}, /* new face */
422 {0, /* null-terminating sentinel */}},
423 bmo_bridge_loops_exec,
427 static BMOpDefine bmo_edgenet_fill_def = {
429 {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edge */
430 {BMO_OP_SLOT_MAPPING, "restrict"}, /* restricts edges to groups. maps edges to integer */
431 {BMO_OP_SLOT_BOOL, "use_restrict"},
432 {BMO_OP_SLOT_BOOL, "use_fill_check"},
433 {BMO_OP_SLOT_ELEMENT_BUF, "excludefaces"}, /* list of faces to ignore for manifold check */
434 {BMO_OP_SLOT_MAPPING, "faceout_groupmap"}, /* maps new faces to the group numbers they came fro */
435 {BMO_OP_SLOT_ELEMENT_BUF, "faceout"}, /* new face */
436 {BMO_OP_SLOT_INT, "mat_nr"}, /* material to use */
437 {BMO_OP_SLOT_BOOL, "use_smooth"}, /* material to use */
438 {0, /* null-terminating sentinel */}},
439 bmo_edgenet_fill_exec,
446 * Identifies several useful edge loop cases and modifies them so
447 * they'll become a face when edgenet_fill is called. The cases covered are:
449 * - One single loop; an edge is added to connect the ends
450 * - Two loops; two edges are added to connect the endpoints (based on the
451 * shortest distance between each endpont).
453 static BMOpDefine bmo_edgenet_prepare_def = {
455 {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, //input edges
456 {BMO_OP_SLOT_ELEMENT_BUF, "edgeout"}, //new edges
457 {0, /* null-terminating sentinel */}},
465 * Rotate vertices around a center, using a 3x3 rotation
466 * matrix. Equivalent of the old rotateflag function.
468 static BMOpDefine bmo_rotate_def = {
470 {{BMO_OP_SLOT_VEC, "cent"}, //center of rotation
471 {BMO_OP_SLOT_MAT, "mat"}, //matrix defining rotation
472 {BMO_OP_SLOT_ELEMENT_BUF, "verts"}, //input vertices
473 {0, /* null-terminating sentinel */}},
481 * Translate vertices by an offset. Equivalent of the
482 * old translateflag function.
484 static BMOpDefine bmo_translate_def = {
486 {{BMO_OP_SLOT_VEC, "vec"}, //translation offset
487 {BMO_OP_SLOT_ELEMENT_BUF, "verts"}, //input vertices
488 {0, /* null-terminating sentinel */}},
496 * Scales vertices by an offset.
498 static BMOpDefine bmo_scale_def = {
500 {{BMO_OP_SLOT_VEC, "vec"}, //scale factor
501 {BMO_OP_SLOT_ELEMENT_BUF, "verts"}, //input vertices
502 {0, /* null-terminating sentinel */}},
511 * Transforms a set of vertices by a matrix. Multiplies
512 * the vertex coordinates with the matrix.
514 static BMOpDefine bmo_transform_def = {
516 {{BMO_OP_SLOT_MAT, "mat"}, //transform matrix
517 {BMO_OP_SLOT_ELEMENT_BUF, "verts"}, //input vertices
518 {0, /* null-terminating sentinel */}},
526 * Loads a bmesh into an object/mesh. This is a "private"
529 static BMOpDefine bmo_object_load_bmesh_def = {
531 {{BMO_OP_SLOT_PNT, "scene"},
532 {BMO_OP_SLOT_PNT, "object"},
533 {0, /* null-terminating sentinel */}},
534 bmo_object_load_bmesh_exec,
542 * Converts a bmesh to a Mesh. This is reserved for exiting editmode.
544 static BMOpDefine bmo_bmesh_to_mesh_def = {
546 {{BMO_OP_SLOT_PNT, "mesh"}, //pointer to a mesh structure to fill in
547 {BMO_OP_SLOT_PNT, "object"}, //pointer to an object structure
548 {BMO_OP_SLOT_BOOL, "notessellation"}, //don't calculate mfaces
549 {0, /* null-terminating sentinel */}},
550 bmo_bmesh_to_mesh_exec,
557 * Load the contents of a mesh into the bmesh. this bmop is private, it's
558 * reserved exclusively for entering editmode.
560 static BMOpDefine bmo_mesh_to_bmesh_def = {
562 {{BMO_OP_SLOT_PNT, "mesh"}, //pointer to a Mesh structure
563 {BMO_OP_SLOT_PNT, "object"}, //pointer to an Object structure
564 {BMO_OP_SLOT_BOOL, "set_shapekey"}, //load active shapekey coordinates into verts
565 {0, /* null-terminating sentinel */}},
566 bmo_mesh_to_bmesh_exec,
571 * Individual Face Extrude
573 * Extrudes faces individually.
575 static BMOpDefine bmo_extrude_indivface_def = {
576 "extrude_face_indiv",
577 {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, //input faces
578 {BMO_OP_SLOT_ELEMENT_BUF, "faceout"}, //output faces
579 {BMO_OP_SLOT_ELEMENT_BUF, "skirtout"}, //output skirt geometry, faces and edges
580 {0} /* null-terminating sentinel */},
581 bmo_extrude_face_indiv_exec,
588 * Extrudes Edges into faces, note that this is very simple, there's no fancy
591 static BMOpDefine bmo_extrude_edge_only_def = {
593 {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, //input vertices
594 {BMO_OP_SLOT_ELEMENT_BUF, "geomout"}, //output geometry
595 {0} /* null-terminating sentinel */},
596 bmo_extrude_edge_only_exec,
601 * Individual Vertex Extrude
603 * Extrudes wire edges from vertices.
605 static BMOpDefine bmo_extrude_vert_indiv_def = {
606 "extrude_vert_indiv",
607 {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, //input vertices
608 {BMO_OP_SLOT_ELEMENT_BUF, "edgeout"}, //output wire edges
609 {BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, //output vertices
610 {0} /* null-terminating sentinel */},
611 bmo_extrude_vert_indiv_exec,
615 static BMOpDefine bmo_connectverts_def = {
617 {{BMO_OP_SLOT_ELEMENT_BUF, "verts"},
618 {BMO_OP_SLOT_ELEMENT_BUF, "edgeout"},
619 {0} /* null-terminating sentinel */},
620 bmo_connectverts_exec,
621 BMO_OP_FLAG_UNTAN_MULTIRES
624 static BMOpDefine bmo_extrude_face_region_def = {
625 "extrude_face_region",
626 {{BMO_OP_SLOT_ELEMENT_BUF, "edgefacein"},
627 {BMO_OP_SLOT_MAPPING, "exclude"},
628 {BMO_OP_SLOT_BOOL, "alwayskeeporig"},
629 {BMO_OP_SLOT_ELEMENT_BUF, "geomout"},
630 {0} /* null-terminating sentinel */},
631 bmo_extrude_face_region_exec,
635 static BMOpDefine bmo_dissolve_verts_def = {
637 {{BMO_OP_SLOT_ELEMENT_BUF, "verts"},
638 {0} /* null-terminating sentinel */},
639 bmo_dissolve_verts_exec,
640 BMO_OP_FLAG_UNTAN_MULTIRES
643 static BMOpDefine bmo_dissolve_edges_def = {
645 {{BMO_OP_SLOT_ELEMENT_BUF, "edges"},
646 {BMO_OP_SLOT_ELEMENT_BUF, "regionout"},
647 {BMO_OP_SLOT_BOOL, "use_verts"}, // dissolve verts left between only 2 edges.
648 {0} /* null-terminating sentinel */},
649 bmo_dissolve_edges_exec,
650 BMO_OP_FLAG_UNTAN_MULTIRES
653 static BMOpDefine bmo_dissolve_edge_loop_def = {
654 "dissolve_edge_loop",
655 {{BMO_OP_SLOT_ELEMENT_BUF, "edges"},
656 {BMO_OP_SLOT_ELEMENT_BUF, "regionout"},
657 {0} /* null-terminating sentinel */},
658 bmo_dissolve_edgeloop_exec,
659 BMO_OP_FLAG_UNTAN_MULTIRES
662 static BMOpDefine bmo_dissolve_faces_def = {
664 {{BMO_OP_SLOT_ELEMENT_BUF, "faces"},
665 {BMO_OP_SLOT_ELEMENT_BUF, "regionout"},
666 {BMO_OP_SLOT_BOOL, "use_verts"}, // dissolve verts left between only 2 edges.
667 {0} /* null-terminating sentinel */},
668 bmo_dissolve_faces_exec,
669 BMO_OP_FLAG_UNTAN_MULTIRES
672 static BMOpDefine bmo_dissolve_limit_def = {
674 {{BMO_OP_SLOT_FLT, "angle_limit"}, /* total rotation angle (degrees) */
675 {BMO_OP_SLOT_ELEMENT_BUF, "verts"},
676 {BMO_OP_SLOT_ELEMENT_BUF, "edges"},
677 {0} /* null-terminating sentinel */},
678 bmo_dissolve_limit_exec,
679 BMO_OP_FLAG_UNTAN_MULTIRES
682 static BMOpDefine bmo_triangulate_def = {
684 {{BMO_OP_SLOT_ELEMENT_BUF, "faces"},
685 {BMO_OP_SLOT_ELEMENT_BUF, "edgeout"},
686 {BMO_OP_SLOT_ELEMENT_BUF, "faceout"},
687 {BMO_OP_SLOT_MAPPING, "facemap"},
688 {BMO_OP_SLOT_BOOL, "use_beauty"},
689 {0} /* null-terminating sentinel */},
690 bmo_triangulate_exec,
691 BMO_OP_FLAG_UNTAN_MULTIRES
694 static BMOpDefine bmo_esubd_def = {
696 {{BMO_OP_SLOT_ELEMENT_BUF, "edges"},
697 {BMO_OP_SLOT_FLT, "smooth"},
698 {BMO_OP_SLOT_FLT, "fractal"},
699 {BMO_OP_SLOT_INT, "numcuts"},
700 {BMO_OP_SLOT_INT, "seed"},
701 {BMO_OP_SLOT_MAPPING, "custompatterns"},
702 {BMO_OP_SLOT_MAPPING, "edgepercents"},
704 /* these next three can have multiple types of elements in them */
705 {BMO_OP_SLOT_ELEMENT_BUF, "outinner"},
706 {BMO_OP_SLOT_ELEMENT_BUF, "outsplit"},
707 {BMO_OP_SLOT_ELEMENT_BUF, "geomout"}, /* contains all output geometr */
709 {BMO_OP_SLOT_INT, "quadcornertype"}, /* quad corner type, see bmesh_operators.h */
710 {BMO_OP_SLOT_BOOL, "use_gridfill"}, /* fill in fully-selected faces with a grid */
711 {BMO_OP_SLOT_BOOL, "use_singleedge"}, /* tessellate the case of one edge selected in a quad or triangle */
712 {BMO_OP_SLOT_BOOL, "use_sphere"}, /* for making new primitives only */
714 {0} /* null-terminating sentinel */,
717 BMO_OP_FLAG_UNTAN_MULTIRES
720 static BMOpDefine bmo_del_def = {
722 {{BMO_OP_SLOT_ELEMENT_BUF, "geom"},
723 {BMO_OP_SLOT_INT, "context"},
724 {0} /* null-terminating sentinel */},
729 static BMOpDefine bmo_dupe_def = {
731 {{BMO_OP_SLOT_ELEMENT_BUF, "geom"},
732 {BMO_OP_SLOT_ELEMENT_BUF, "origout"},
733 {BMO_OP_SLOT_ELEMENT_BUF, "newout"},
734 /* facemap maps from source faces to dupe
735 * faces, and from dupe faces to source faces */
736 {BMO_OP_SLOT_MAPPING, "facemap"},
737 {BMO_OP_SLOT_MAPPING, "boundarymap"},
738 {BMO_OP_SLOT_MAPPING, "isovertmap"},
739 {BMO_OP_SLOT_PNT, "dest"}, /* destination bmesh, if NULL will use current on */
740 {0} /* null-terminating sentinel */},
745 static BMOpDefine bmo_split_def = {
747 {{BMO_OP_SLOT_ELEMENT_BUF, "geom"},
748 {BMO_OP_SLOT_ELEMENT_BUF, "geomout"},
749 {BMO_OP_SLOT_MAPPING, "boundarymap"},
750 {BMO_OP_SLOT_MAPPING, "isovertmap"},
751 {BMO_OP_SLOT_PNT, "dest"}, /* destination bmesh, if NULL will use current on */
752 {BMO_OP_SLOT_BOOL, "use_only_faces"}, /* when enabled. don't duplicate loose verts/edges */
753 {0} /* null-terminating sentinel */},
761 * Extrude or duplicate geometry a number of times,
762 * rotating and possibly translating after each step
764 static BMOpDefine bmo_spin_def = {
766 {{BMO_OP_SLOT_ELEMENT_BUF, "geom"},
767 {BMO_OP_SLOT_ELEMENT_BUF, "lastout"}, /* result of last step */
768 {BMO_OP_SLOT_VEC, "cent"}, /* rotation center */
769 {BMO_OP_SLOT_VEC, "axis"}, /* rotation axis */
770 {BMO_OP_SLOT_VEC, "dvec"}, /* translation delta per step */
771 {BMO_OP_SLOT_FLT, "ang"}, /* total rotation angle (degrees) */
772 {BMO_OP_SLOT_INT, "steps"}, /* number of steps */
773 {BMO_OP_SLOT_BOOL, "do_dupli"}, /* duplicate or extrude? */
774 {0} /* null-terminating sentinel */},
781 * Similar faces search
783 * Find similar faces (area/material/perimeter, ...).
785 static BMOpDefine bmo_similarfaces_def = {
787 {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
788 {BMO_OP_SLOT_ELEMENT_BUF, "faceout"}, /* output faces */
789 {BMO_OP_SLOT_INT, "type"}, /* type of selection */
790 {BMO_OP_SLOT_FLT, "thresh"}, /* threshold of selection */
791 {0} /* null-terminating sentinel */},
792 bmo_similarfaces_exec,
797 * Similar edges search
799 * Find similar edges (length, direction, edge, seam, ...).
801 static BMOpDefine bmo_similaredges_def = {
803 {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edges */
804 {BMO_OP_SLOT_ELEMENT_BUF, "edgeout"}, /* output edges */
805 {BMO_OP_SLOT_INT, "type"}, /* type of selection */
806 {BMO_OP_SLOT_FLT, "thresh"}, /* threshold of selection */
807 {0} /* null-terminating sentinel */},
808 bmo_similaredges_exec,
813 * Similar vertices search
815 * Find similar vertices (normal, face, vertex group, ...).
817 static BMOpDefine bmo_similarverts_def = {
819 {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */
820 {BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, /* output vertices */
821 {BMO_OP_SLOT_INT, "type"}, /* type of selection */
822 {BMO_OP_SLOT_FLT, "thresh"}, /* threshold of selection */
823 {0} /* null-terminating sentinel */},
824 bmo_similarverts_exec,
832 static BMOpDefine bmo_face_rotateuvs_def = {
834 {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
835 {BMO_OP_SLOT_INT, "dir"}, /* direction */
836 {0} /* null-terminating sentinel */},
837 bmo_face_rotateuvs_exec,
845 static BMOpDefine bmo_face_reverseuvs_def = {
847 {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
848 {0} /* null-terminating sentinel */},
849 bmo_face_reverseuvs_exec,
857 static BMOpDefine bmo_face_rotatecolors_def = {
859 {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
860 {BMO_OP_SLOT_INT, "dir"}, /* direction */
861 {0} /* null-terminating sentinel */},
862 bmo_rotatecolors_exec,
870 static BMOpDefine bmo_face_reversecolors_def = {
871 "face_reversecolors",
872 {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
873 {0} /* null-terminating sentinel */},
874 bmo_face_reversecolors_exec,
879 * Similar vertices search
881 * Find similar vertices (normal, face, vertex group, ...).
883 static BMOpDefine bmo_vertexshortestpath_def = {
884 "vertexshortestpath",
885 {{BMO_OP_SLOT_ELEMENT_BUF, "startv"}, /* start vertex */
886 {BMO_OP_SLOT_ELEMENT_BUF, "endv"}, /* end vertex */
887 {BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, /* output vertices */
888 {BMO_OP_SLOT_INT, "type"}, /* type of selection */
889 {0} /* null-terminating sentinel */},
890 bmo_vertexshortestpath_exec,
897 * Disconnects faces along input edges.
899 static BMOpDefine bmo_edgesplit_def = {
901 {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edges */
902 {BMO_OP_SLOT_ELEMENT_BUF, "edgeout"}, /* old output disconnected edges */
903 /* needed for vertex rip so we can rip only half an edge at a boundary wich would otherwise split off */
904 {BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* optional tag verts, use to have greater control of splits */
905 {BMO_OP_SLOT_BOOL, "use_verts"}, /* use 'verts' for splitting, else just find verts to split from edges */
906 {0} /* null-terminating sentinel */},
908 BMO_OP_FLAG_UNTAN_MULTIRES
914 * Creates a grid with a variable number of subdivisions
916 static BMOpDefine bmo_create_grid_def = {
918 {{BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, //output verts
919 {BMO_OP_SLOT_INT, "xsegments"}, //number of x segments
920 {BMO_OP_SLOT_INT, "ysegments"}, //number of y segments
921 {BMO_OP_SLOT_FLT, "size"}, //size of the grid
922 {BMO_OP_SLOT_MAT, "mat"}, //matrix to multiply the new geometry with
923 {0, /* null-terminating sentinel */}},
924 bmo_create_grid_exec,
931 * Creates a grid with a variable number of subdivisions
933 static BMOpDefine bmo_create_uvsphere_def = {
935 {{BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, //output verts
936 {BMO_OP_SLOT_INT, "segments"}, //number of u segments
937 {BMO_OP_SLOT_INT, "revolutions"}, //number of v segment
938 {BMO_OP_SLOT_FLT, "diameter"}, //diameter
939 {BMO_OP_SLOT_MAT, "mat"}, //matrix to multiply the new geometry with--
940 {0, /* null-terminating sentinel */}},
941 bmo_create_uvsphere_exec,
948 * Creates a grid with a variable number of subdivisions
950 static BMOpDefine bmo_create_icosphere_def = {
952 {{BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, //output verts
953 {BMO_OP_SLOT_INT, "subdivisions"}, //how many times to recursively subdivide the sphere
954 {BMO_OP_SLOT_FLT, "diameter"}, //diameter
955 {BMO_OP_SLOT_MAT, "mat"}, //matrix to multiply the new geometry with
956 {0, /* null-terminating sentinel */}},
957 bmo_create_icosphere_exec,
964 * Creates a monkey. Be wary.
966 static BMOpDefine bmo_create_monkey_def = {
968 {{BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, //output verts
969 {BMO_OP_SLOT_MAT, "mat"}, //matrix to multiply the new geometry with--
970 {0, /* null-terminating sentinel */}},
971 bmo_create_monkey_exec,
978 * Creates a cone with variable depth at both ends
980 static BMOpDefine bmo_create_cone_def = {
982 {{BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, //output verts
983 {BMO_OP_SLOT_BOOL, "cap_ends"}, //wheter or not to fill in the ends with faces
984 {BMO_OP_SLOT_BOOL, "cap_tris"}, //fill ends with triangles instead of ngons
985 {BMO_OP_SLOT_INT, "segments"},
986 {BMO_OP_SLOT_FLT, "diameter1"}, //diameter of one end
987 {BMO_OP_SLOT_FLT, "diameter2"}, //diameter of the opposite
988 {BMO_OP_SLOT_FLT, "depth"}, //distance between ends
989 {BMO_OP_SLOT_MAT, "mat"}, //matrix to multiply the new geometry with--
990 {0, /* null-terminating sentinel */}},
991 bmo_create_cone_exec,
998 static BMOpDefine bmo_create_circle_def = {
1000 {{BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, //output verts
1001 {BMO_OP_SLOT_BOOL, "cap_ends"}, //wheter or not to fill in the ends with faces
1002 {BMO_OP_SLOT_BOOL, "cap_tris"}, //fill ends with triangles instead of ngons
1003 {BMO_OP_SLOT_INT, "segments"},
1004 {BMO_OP_SLOT_FLT, "diameter"}, //diameter of one end
1005 {BMO_OP_SLOT_MAT, "mat"}, //matrix to multiply the new geometry with--
1006 {0, /* null-terminating sentinel */}},
1007 bmo_create_circle_exec,
1014 * Creates a cone with variable depth at both ends
1016 static BMOpDefine bmo_create_cube_def = {
1018 {{BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, //output verts
1019 {BMO_OP_SLOT_FLT, "size"}, //size of the cube
1020 {BMO_OP_SLOT_MAT, "mat"}, //matrix to multiply the new geometry with--
1021 {0, /* null-terminating sentinel */}},
1022 bmo_create_cube_exec,
1029 * Bevels edges and vertices
1031 static BMOpDefine bmo_bevel_def = {
1033 {{BMO_OP_SLOT_ELEMENT_BUF, "geom"}, /* input edges and vertices */
1034 {BMO_OP_SLOT_ELEMENT_BUF, "face_spans"}, /* new geometry */
1035 {BMO_OP_SLOT_ELEMENT_BUF, "face_holes"}, /* new geometry */
1036 {BMO_OP_SLOT_BOOL, "use_lengths"}, /* grab edge lengths from a PROP_FLT customdata laye */
1037 {BMO_OP_SLOT_BOOL, "use_even"}, /* corner vert placement: use shell/angle calculations */
1038 {BMO_OP_SLOT_BOOL, "use_dist"}, /* corner vert placement: evaluate percent as a distance,
1039 * modifier uses this. We could do this as another float setting */
1040 {BMO_OP_SLOT_INT, "lengthlayer"}, /* which PROP_FLT layer to us */
1041 {BMO_OP_SLOT_FLT, "percent"}, /* percentage to expand bevelled edge */
1042 {0} /* null-terminating sentinel */},
1044 BMO_OP_FLAG_UNTAN_MULTIRES
1050 * Makes triangle a bit nicer
1052 static BMOpDefine bmo_beautify_fill_def = {
1054 {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
1055 {BMO_OP_SLOT_ELEMENT_BUF, "constrain_edges"}, /* edges that can't be flipped */
1056 {BMO_OP_SLOT_ELEMENT_BUF, "geomout"}, /* new flipped faces and edges */
1057 {0} /* null-terminating sentinel */},
1058 bmo_beautify_fill_exec,
1059 BMO_OP_FLAG_UNTAN_MULTIRES
1065 * Fill edges with triangles
1067 static BMOpDefine bmo_triangle_fill_def = {
1069 {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edges */
1070 {BMO_OP_SLOT_ELEMENT_BUF, "geomout"}, /* new faces and edges */
1071 {0} /* null-terminating sentinel */},
1072 bmo_triangle_fill_exec,
1073 BMO_OP_FLAG_UNTAN_MULTIRES
1079 * Turns a mesh into a shell with thickness
1081 static BMOpDefine bmo_solidify_def = {
1083 {{BMO_OP_SLOT_ELEMENT_BUF, "geom"},
1084 {BMO_OP_SLOT_FLT, "thickness"},
1085 {BMO_OP_SLOT_ELEMENT_BUF, "geomout"},
1087 bmo_solidify_face_region_exec,
1094 * Extrudes faces individually.
1096 static BMOpDefine bmo_inset_def = {
1098 {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
1099 {BMO_OP_SLOT_ELEMENT_BUF, "faceout"}, /* output faces */
1100 {BMO_OP_SLOT_BOOL, "use_boundary"},
1101 {BMO_OP_SLOT_BOOL, "use_even_offset"},
1102 {BMO_OP_SLOT_BOOL, "use_relative_offset"},
1103 {BMO_OP_SLOT_FLT, "thickness"},
1104 {BMO_OP_SLOT_FLT, "depth"},
1105 {BMO_OP_SLOT_BOOL, "use_outset"},
1106 {0} /* null-terminating sentinel */},
1114 * Makes a wire copy of faces.
1116 static BMOpDefine bmo_wireframe_def = {
1118 {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
1119 {BMO_OP_SLOT_ELEMENT_BUF, "faceout"}, /* output faces */
1120 {BMO_OP_SLOT_BOOL, "use_boundary"},
1121 {BMO_OP_SLOT_BOOL, "use_even_offset"},
1122 {BMO_OP_SLOT_BOOL, "use_crease"},
1123 {BMO_OP_SLOT_FLT, "thickness"},
1124 {BMO_OP_SLOT_BOOL, "use_relative_offset"},
1125 {BMO_OP_SLOT_FLT, "depth"},
1126 {0} /* null-terminating sentinel */},
1134 * Translates vertes along an edge
1136 static BMOpDefine bmo_vertex_slide_def = {
1138 {{BMO_OP_SLOT_ELEMENT_BUF, "vert"},
1139 {BMO_OP_SLOT_ELEMENT_BUF, "edge"},
1140 {BMO_OP_SLOT_ELEMENT_BUF, "vertout"},
1141 {BMO_OP_SLOT_FLT, "distance_t"},
1142 {0} /* null-terminating sentinel */},
1143 bmo_vertex_slide_exec,
1144 BMO_OP_FLAG_UNTAN_MULTIRES
1150 * Builds a convex hull from the vertices in 'input'.
1152 * If 'use_existing_faces' is true, the hull will not output triangles
1153 * that are covered by a pre-existing face.
1155 * All hull vertices, faces, and edges are added to 'geomout'. Any
1156 * input elements that end up inside the hull (i.e. are not used by an
1157 * output face) are added to the 'interior_geom' slot. The
1158 * 'unused_geom' slot will contain all interior geometry that is
1159 * completely unused. Lastly, 'holes_geom' contains edges and faces
1160 * that were in the input and are part of the hull.
1162 static BMOpDefine bmo_convex_hull_def = {
1164 {{BMO_OP_SLOT_ELEMENT_BUF, "input"},
1165 {BMO_OP_SLOT_BOOL, "use_existing_faces"},
1168 {BMO_OP_SLOT_ELEMENT_BUF, "geomout"},
1169 {BMO_OP_SLOT_ELEMENT_BUF, "interior_geom"},
1170 {BMO_OP_SLOT_ELEMENT_BUF, "unused_geom"},
1171 {BMO_OP_SLOT_ELEMENT_BUF, "holes_geom"},
1172 {0} /* null-terminating sentinel */},
1173 bmo_convex_hull_exec,
1177 BMOpDefine *opdefines[] = {
1183 &bmo_triangulate_def,
1184 &bmo_dissolve_faces_def,
1185 &bmo_dissolve_edges_def,
1186 &bmo_dissolve_edge_loop_def,
1187 &bmo_dissolve_verts_def,
1188 &bmo_dissolve_limit_def,
1189 &bmo_extrude_face_region_def,
1190 &bmo_connectverts_def,
1191 &bmo_extrude_vert_indiv_def,
1192 &bmo_mesh_to_bmesh_def,
1193 &bmo_object_load_bmesh_def,
1197 &bmo_edgenet_fill_def,
1198 &bmo_contextual_create_def,
1201 &bmo_removedoubles_def,
1202 &bmo_finddoubles_def,
1204 &bmo_edgebisect_def,
1205 &bmo_reversefaces_def,
1206 &bmo_edgerotate_def,
1207 &bmo_regionextend_def,
1208 &bmo_righthandfaces_def,
1209 &bmo_vertexsmooth_def,
1210 &bmo_extrude_edge_only_def,
1211 &bmo_extrude_indivface_def,
1212 &bmo_collapse_uvs_def,
1213 &bmo_pointmerge_def,
1215 &bmo_similarfaces_def,
1216 &bmo_similaredges_def,
1217 &bmo_similarverts_def,
1218 &bmo_pointmerge_facedata_def,
1219 &bmo_vert_average_facedata_def,
1220 &bmo_face_rotateuvs_def,
1221 &bmo_bmesh_to_mesh_def,
1222 &bmo_face_reverseuvs_def,
1223 &bmo_edgenet_prepare_def,
1224 &bmo_face_rotatecolors_def,
1225 &bmo_face_reversecolors_def,
1226 &bmo_vertexshortestpath_def,
1230 &bmo_create_uvsphere_def,
1231 &bmo_create_grid_def,
1232 &bmo_create_icosphere_def,
1233 &bmo_create_monkey_def,
1234 &bmo_create_cube_def,
1235 &bmo_create_circle_def,
1236 &bmo_create_cone_def,
1237 &bmo_join_triangles_def,
1239 &bmo_beautify_fill_def,
1240 &bmo_triangle_fill_def,
1241 &bmo_bridge_loops_def,
1245 &bmo_vertex_slide_def,
1246 &bmo_convex_hull_def,
1249 int bmesh_total_ops = (sizeof(opdefines) / sizeof(void *));