doxygen: add newline after \file
[blender.git] / source / blender / bmesh / intern / bmesh_operator_api.h
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16
17 #ifndef __BMESH_OPERATOR_API_H__
18 #define __BMESH_OPERATOR_API_H__
19
20 /** \file
21  * \ingroup bmesh
22  */
23
24 #ifdef __cplusplus
25 extern "C" {
26 #endif
27
28 #include "BLI_ghash.h"
29
30 #include <stdarg.h>
31
32 /**
33  * operators represent logical, executable mesh modules.  all topological
34  * operations involving a bmesh has to go through them.
35  *
36  * operators are nested, as are tool flags, which are private to an operator
37  * when it's executed.  tool flags are allocated in layers, one per operator
38  * execution, and are used for all internal flagging a tool needs to do.
39  *
40  * each operator has a series of "slots" which can be of the following types:
41  * - simple numerical types
42  * - arrays of elements (e.g. arrays of faces).
43  * - hash mappings.
44  *
45  * each slot is identified by a slot code, as are each operator.
46  * operators, and their slots, are defined in bmesh_opdefines.c (with their
47  * execution functions prototyped in bmesh_operators_private.h), with all their
48  * operator code and slot codes defined in bmesh_operators.h.  see
49  * bmesh_opdefines.c and the BMOpDefine struct for how to define new operators.
50  *
51  * in general, operators are fed arrays of elements, created using either
52  * #BMO_slot_buffer_from_hflag or #BMO_slot_buffer_from_flag
53  * (or through one of the format specifiers in #BMO_op_callf or #BMO_op_initf).
54  *
55  * \note multiple element types (e.g. faces and edges)
56  * can be fed to the same slot array.  Operators act on this data,
57  * and possibly spit out data into output slots.
58  *
59  * \note operators should never read from header flags (e.g. element->head.flag).
60  * For example, if you want an operator to only operate on selected faces, you
61  * should use #BMO_slot_buffer_from_hflag to put the selected elements into a slot.
62  *
63  * \note when you read from an element slot array or mapping, you can either tool-flag
64  * all the elements in it, or read them using an iterator API (which is semantically
65  * similar to the iterator api in bmesh_iterators.h).
66  *
67  * \note only #BMLoop items can't be put into slots as with verts, edges & faces.
68  */
69
70 struct GHashIterator;
71
72 BLI_INLINE BMFlagLayer *BMO_elem_flag_from_header(BMHeader *ele_head)
73 {
74         switch (ele_head->htype) {
75                 case BM_VERT: return ((BMVert_OFlag *)ele_head)->oflags;
76                 case BM_EDGE: return ((BMEdge_OFlag *)ele_head)->oflags;
77                 default:      return ((BMFace_OFlag *)ele_head)->oflags;
78         }
79 }
80
81 #define BMO_elem_flag_test(bm, ele, oflag) \
82         _bmo_elem_flag_test(bm, BMO_elem_flag_from_header(&(ele)->head), oflag)
83 #define BMO_elem_flag_test_bool(bm, ele, oflag) \
84         _bmo_elem_flag_test_bool(bm, BMO_elem_flag_from_header(&(ele)->head), oflag)
85 #define BMO_elem_flag_enable(bm, ele, oflag) \
86         _bmo_elem_flag_enable(bm, (BM_CHECK_TYPE_ELEM_NONCONST(ele), BMO_elem_flag_from_header(&(ele)->head)), oflag)
87 #define BMO_elem_flag_disable(bm, ele, oflag) \
88         _bmo_elem_flag_disable(bm, (BM_CHECK_TYPE_ELEM_NONCONST(ele), BMO_elem_flag_from_header(&(ele)->head)), oflag)
89 #define BMO_elem_flag_set(bm, ele, oflag, val) \
90         _bmo_elem_flag_set(bm, (BM_CHECK_TYPE_ELEM_NONCONST(ele), BMO_elem_flag_from_header(&(ele)->head)), oflag, val)
91 #define BMO_elem_flag_toggle(bm, ele, oflag) \
92         _bmo_elem_flag_toggle(bm, (BM_CHECK_TYPE_ELEM_NONCONST(ele), BMO_elem_flag_from_header(&(ele)->head)), oflag)
93
94 /* take care not to instansiate args multiple times */
95 #ifdef __GNUC___
96 #define _BMO_CAST_V_CONST(e) ({ typeof(e) _e = e; \
97         (BM_CHECK_TYPE_VERT(_e), BLI_assert(((const BMHeader *)_e)->htype == BM_VERT), (const BMVert_OFlag *)_e); })
98 #define _BMO_CAST_E_CONST(e) ({ typeof(e) _e = e; \
99         (BM_CHECK_TYPE_EDGE(_e), BLI_assert(((const BMHeader *)_e)->htype == BM_EDGE), (const BMEdge_OFlag *)_e); })
100 #define _BMO_CAST_F_CONST(e) ({ typeof(e) _e = e; \
101         (BM_CHECK_TYPE_FACE(_e), BLI_assert(((const BMHeader *)_e)->htype == BM_FACE), (const BMFace_OFlag *)_e); })
102 #define _BMO_CAST_V(e) ({ typeof(e) _e = e; \
103         (BM_CHECK_TYPE_VERT_NONCONST(_e), BLI_assert(((BMHeader *)_e)->htype == BM_VERT), (BMVert_OFlag *)_e); })
104 #define _BMO_CAST_E(e) ({ typeof(e) _e = e; \
105         (BM_CHECK_TYPE_EDGE_NONCONST(_e), BLI_assert(((BMHeader *)_e)->htype == BM_EDGE), (BMEdge_OFlag *)_e); })
106 #define _BMO_CAST_F(e) ({ typeof(e) _e = e; \
107         (BM_CHECK_TYPE_FACE_NONCONST(_e), BLI_assert(((BMHeader *)_e)->htype == BM_FACE), (BMFace_OFlag *)_e); })
108 #else
109 #define _BMO_CAST_V_CONST(e) (BM_CHECK_TYPE_VERT(e), (const BMVert_OFlag *)e)
110 #define _BMO_CAST_E_CONST(e) (BM_CHECK_TYPE_EDGE(e), (const BMEdge_OFlag *)e)
111 #define _BMO_CAST_F_CONST(e) (BM_CHECK_TYPE_FACE(e), (const BMFace_OFlag *)e)
112 #define _BMO_CAST_V(e) (BM_CHECK_TYPE_VERT_NONCONST(e), (BMVert_OFlag *)e)
113 #define _BMO_CAST_E(e) (BM_CHECK_TYPE_EDGE_NONCONST(e), (BMEdge_OFlag *)e)
114 #define _BMO_CAST_F(e) (BM_CHECK_TYPE_FACE_NONCONST(e), (BMFace_OFlag *)e)
115 #endif
116
117 #define BMO_vert_flag_test(     bm, e, oflag)      _bmo_elem_flag_test     (bm, _BMO_CAST_V_CONST(e)->oflags, oflag)
118 #define BMO_vert_flag_test_bool(bm, e, oflag)      _bmo_elem_flag_test_bool(bm, _BMO_CAST_V_CONST(e)->oflags, oflag)
119 #define BMO_vert_flag_enable(   bm, e, oflag)      _bmo_elem_flag_enable   (bm, _BMO_CAST_V(e)->oflags, oflag)
120 #define BMO_vert_flag_disable(  bm, e, oflag)      _bmo_elem_flag_disable  (bm, _BMO_CAST_V(e)->oflags, oflag)
121 #define BMO_vert_flag_set(      bm, e, oflag, val) _bmo_elem_flag_set      (bm, _BMO_CAST_V(e)->oflags, oflag, val)
122 #define BMO_vert_flag_toggle(   bm, e, oflag)      _bmo_elem_flag_toggle   (bm, _BMO_CAST_V(e)->oflags, oflag)
123
124 #define BMO_edge_flag_test(     bm, e, oflag)      _bmo_elem_flag_test     (bm, _BMO_CAST_E_CONST(e)->oflags, oflag)
125 #define BMO_edge_flag_test_bool(bm, e, oflag)      _bmo_elem_flag_test_bool(bm, _BMO_CAST_E_CONST(e)->oflags, oflag)
126 #define BMO_edge_flag_enable(   bm, e, oflag)      _bmo_elem_flag_enable   (bm, _BMO_CAST_E(e)->oflags, oflag)
127 #define BMO_edge_flag_disable(  bm, e, oflag)      _bmo_elem_flag_disable  (bm, _BMO_CAST_E(e)->oflags, oflag)
128 #define BMO_edge_flag_set(      bm, e, oflag, val) _bmo_elem_flag_set      (bm, _BMO_CAST_E(e)->oflags, oflag, val)
129 #define BMO_edge_flag_toggle(   bm, e, oflag)      _bmo_elem_flag_toggle   (bm, _BMO_CAST_E(e)->oflags, oflag)
130
131 #define BMO_face_flag_test(     bm, e, oflag)      _bmo_elem_flag_test     (bm, _BMO_CAST_F_CONST(e)->oflags, oflag)
132 #define BMO_face_flag_test_bool(bm, e, oflag)      _bmo_elem_flag_test_bool(bm, _BMO_CAST_F_CONST(e)->oflags, oflag)
133 #define BMO_face_flag_enable(   bm, e, oflag)      _bmo_elem_flag_enable   (bm, _BMO_CAST_F(e)->oflags, oflag)
134 #define BMO_face_flag_disable(  bm, e, oflag)      _bmo_elem_flag_disable  (bm, _BMO_CAST_F(e)->oflags, oflag)
135 #define BMO_face_flag_set(      bm, e, oflag, val) _bmo_elem_flag_set      (bm, _BMO_CAST_F(e)->oflags, oflag, val)
136 #define BMO_face_flag_toggle(   bm, e, oflag)      _bmo_elem_flag_toggle   (bm, _BMO_CAST_F(e)->oflags, oflag)
137
138 BLI_INLINE short _bmo_elem_flag_test(     BMesh *bm, const BMFlagLayer *oflags, const short oflag);
139 BLI_INLINE bool  _bmo_elem_flag_test_bool(BMesh *bm, const BMFlagLayer *oflags, const short oflag);
140 BLI_INLINE void  _bmo_elem_flag_enable(   BMesh *bm, BMFlagLayer *oflags, const short oflag);
141 BLI_INLINE void  _bmo_elem_flag_disable(  BMesh *bm, BMFlagLayer *oflags, const short oflag);
142 BLI_INLINE void  _bmo_elem_flag_set(      BMesh *bm, BMFlagLayer *oflags, const short oflag, int val);
143 BLI_INLINE void  _bmo_elem_flag_toggle(   BMesh *bm, BMFlagLayer *oflags, const short oflag);
144
145 /* slot type arrays are terminated by the last member
146  * having a slot type of 0 */
147 typedef enum eBMOpSlotType {
148         /* BMO_OP_SLOT_SENTINEL = 0, */
149         BMO_OP_SLOT_BOOL = 1,
150         BMO_OP_SLOT_INT = 2,
151         BMO_OP_SLOT_FLT = 3,
152
153         /* normally store pointers to object, scene,
154          * _never_ store arrays corresponding to mesh elements with this */
155         BMO_OP_SLOT_PTR = 4,  /* requres subtype BMO_OP_SLOT_SUBTYPE_PTR_xxx */
156         BMO_OP_SLOT_MAT = 5,
157         BMO_OP_SLOT_VEC = 8,
158
159         /* after BMO_OP_SLOT_VEC, everything is dynamically allocated arrays.
160          * We leave a space in the identifiers for future growth.
161          *
162          * it's very important this remain a power of two */
163         BMO_OP_SLOT_ELEMENT_BUF = 9, /* list of verts/edges/faces */
164         BMO_OP_SLOT_MAPPING = 10 /* simple hash map, requres subtype BMO_OP_SLOT_SUBTYPE_MAP_xxx */
165 } eBMOpSlotType;
166 #define BMO_OP_SLOT_TOTAL_TYPES 11
167
168 /* don't overlap values to avoid confusion */
169 typedef enum eBMOpSlotSubType_Elem {
170         /* use as flags */
171         BMO_OP_SLOT_SUBTYPE_ELEM_VERT = BM_VERT,
172         BMO_OP_SLOT_SUBTYPE_ELEM_EDGE = BM_EDGE,
173         BMO_OP_SLOT_SUBTYPE_ELEM_FACE = BM_FACE,
174         BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE = (BM_FACE << 1),
175 } eBMOpSlotSubType_Elem;
176 typedef enum eBMOpSlotSubType_Map {
177         BMO_OP_SLOT_SUBTYPE_MAP_EMPTY    = 64,  /* use as a set(), unused value */
178         BMO_OP_SLOT_SUBTYPE_MAP_ELEM     = 65,
179         BMO_OP_SLOT_SUBTYPE_MAP_FLT      = 66,
180         BMO_OP_SLOT_SUBTYPE_MAP_INT      = 67,
181         BMO_OP_SLOT_SUBTYPE_MAP_BOOL     = 68,
182         BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL = 69,  /* python can't convert these */
183 } eBMOpSlotSubType_Map;
184 typedef enum eBMOpSlotSubType_Ptr {
185         BMO_OP_SLOT_SUBTYPE_PTR_BMESH  = 100,
186         BMO_OP_SLOT_SUBTYPE_PTR_SCENE  = 101,
187         BMO_OP_SLOT_SUBTYPE_PTR_OBJECT = 102,
188         BMO_OP_SLOT_SUBTYPE_PTR_MESH   = 103,
189 } eBMOpSlotSubType_Ptr;
190 typedef enum eBMOpSlotSubType_Int {
191         BMO_OP_SLOT_SUBTYPE_INT_ENUM = 200,
192         BMO_OP_SLOT_SUBTYPE_INT_FLAG = 201,
193 } eBMOpSlotSubType_Int;
194
195 typedef union eBMOpSlotSubType_Union {
196         eBMOpSlotSubType_Elem elem;
197         eBMOpSlotSubType_Ptr ptr;
198         eBMOpSlotSubType_Map map;
199         eBMOpSlotSubType_Int intg;
200 } eBMOpSlotSubType_Union;
201
202 typedef struct BMO_FlagSet {
203         int value;
204         const char *identifier;
205 } BMO_FlagSet;
206
207 /* please ignore all these structures, don't touch them in tool code, except
208  * for when your defining an operator with BMOpDefine.*/
209
210 typedef struct BMOpSlot {
211         const char *slot_name;  /* pointer to BMOpDefine.slot_args */
212         eBMOpSlotType          slot_type;
213         eBMOpSlotSubType_Union slot_subtype;
214
215         int len;
216 //      int flag;  /* UNUSED */
217 //      int index; /* index within slot array */  /* UNUSED */
218         union {
219                 int i;
220                 float f;
221                 void *p;
222                 float vec[3];
223                 void **buf;
224                 GHash *ghash;
225                 struct {
226                         /** Don't clobber (i) when assigning flags, see #eBMOpSlotSubType_Int. */
227                         int _i;
228                         BMO_FlagSet *flags;
229                 } enum_data;
230         } data;
231 } BMOpSlot;
232
233 /* mainly for use outside bmesh internal code */
234 #define BMO_SLOT_AS_BOOL(slot)         ((slot)->data.i)
235 #define BMO_SLOT_AS_INT(slot)          ((slot)->data.i)
236 #define BMO_SLOT_AS_FLOAT(slot)        ((slot)->data.f)
237 #define BMO_SLOT_AS_VECTOR(slot)       ((slot)->data.vec)
238 #define BMO_SLOT_AS_MATRIX(slot )      ((float (*)[4])((slot)->data.p))
239 #define BMO_SLOT_AS_BUFFER(slot )      ((slot)->data.buf)
240 #define BMO_SLOT_AS_GHASH(slot )       ((slot)->data.ghash)
241
242 #define BMO_ASSERT_SLOT_IN_OP(slot, op) \
243         BLI_assert(((slot >= (op)->slots_in)  && (slot < &(op)->slots_in[BMO_OP_MAX_SLOTS])) || \
244                    ((slot >= (op)->slots_out) && (slot < &(op)->slots_out[BMO_OP_MAX_SLOTS])))
245
246 /* way more than probably needed, compiler complains if limit hit */
247 #define BMO_OP_MAX_SLOTS 20
248
249 /* BMOpDefine->type_flag */
250 typedef enum {
251         BMO_OPTYPE_FLAG_NOP                 = 0,
252         BMO_OPTYPE_FLAG_UNTAN_MULTIRES      = (1 << 0),  /* switch from multires tangent space to absolute coordinates */
253         BMO_OPTYPE_FLAG_NORMALS_CALC        = (1 << 1),
254         BMO_OPTYPE_FLAG_SELECT_FLUSH        = (1 << 2),
255         BMO_OPTYPE_FLAG_SELECT_VALIDATE     = (1 << 3),
256         BMO_OPTYPE_FLAG_INVALIDATE_CLNOR_ALL = (1 << 4),
257 } BMOpTypeFlag;
258
259 typedef struct BMOperator {
260         struct BMOpSlot slots_in[BMO_OP_MAX_SLOTS];
261         struct BMOpSlot slots_out[BMO_OP_MAX_SLOTS];
262         void (*exec)(BMesh *bm, struct BMOperator *op);
263         struct MemArena *arena;
264         int type;
265         BMOpTypeFlag type_flag;
266         int flag;  /* runtime options */
267 } BMOperator;
268
269 enum {
270         BMO_FLAG_RESPECT_HIDE = 1,
271 };
272
273 #define BMO_FLAG_DEFAULTS  BMO_FLAG_RESPECT_HIDE
274
275 #define MAX_SLOTNAME    32
276
277 typedef struct BMOSlotType {
278         char name[MAX_SLOTNAME];
279         eBMOpSlotType          type;
280         eBMOpSlotSubType_Union subtype;
281         BMO_FlagSet            *enum_flags;
282 } BMOSlotType;
283
284 typedef struct BMOpDefine {
285         const char *opname;
286         BMOSlotType slot_types_in[BMO_OP_MAX_SLOTS];
287         BMOSlotType slot_types_out[BMO_OP_MAX_SLOTS];
288         void (*exec)(BMesh *bm, BMOperator *op);
289         BMOpTypeFlag type_flag;
290 } BMOpDefine;
291
292 /*------------- Operator API --------------*/
293
294 /* data types that use pointers (arrays, etc) should never
295  * have it set directly.  and never use BMO_slot_ptr_set to
296  * pass in a list of edges or any arrays, really.*/
297
298 void BMO_op_init(BMesh *bm, BMOperator *op, const int flag, const char *opname);
299
300 /* executes an operator, pushing and popping a new tool flag
301  * layer as appropriate.*/
302 void BMO_op_exec(BMesh *bm, BMOperator *op);
303
304 /* finishes an operator (though note the operator's tool flag is removed
305  * after it finishes executing in BMO_op_exec).*/
306 void BMO_op_finish(BMesh *bm, BMOperator *op);
307
308 /* count the number of elements with the specified flag enabled.
309  * type can be a bitmask of BM_FACE, BM_EDGE, or BM_FACE. */
310 int BMO_mesh_enabled_flag_count(BMesh *bm, const char htype, const short oflag);
311
312 /* count the number of elements with the specified flag disabled.
313  * type can be a bitmask of BM_FACE, BM_EDGE, or BM_FACE. */
314 int BMO_mesh_disabled_flag_count(BMesh *bm, const char htype, const short oflag);
315
316 /*---------formatted operator initialization/execution-----------*/
317 void BMO_push(BMesh *bm, BMOperator *op);
318 void BMO_pop(BMesh *bm);
319
320 /*executes an operator*/
321 bool BMO_op_callf(BMesh *bm, const int flag, const char *fmt, ...);
322
323 /* initializes, but doesn't execute an operator.  this is so you can
324  * gain access to the outputs of the operator.  note that you have
325  * to execute/finish (BMO_op_exec and BMO_op_finish) yourself. */
326 bool BMO_op_initf(BMesh *bm, BMOperator *op, const int flag, const char *fmt, ...);
327
328 /* va_list version, used to implement the above two functions,
329  * plus EDBM_op_callf in editmesh_utils.c. */
330 bool BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *fmt, va_list vlist);
331
332 /* test whether a named slot exists */
333 bool BMO_slot_exists(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *identifier);
334
335 /* get a pointer to a slot.  this may be removed layer on from the public API. */
336 BMOpSlot *BMO_slot_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *identifier);
337
338 /* copies the data of a slot from one operator to another.  src and dst are the
339  * source/destination slot codes, respectively. */
340 #define BMO_slot_copy(op_src, slots_src, slot_name_src,                       \
341                       op_dst, slots_dst, slot_name_dst)                       \
342         _bmo_slot_copy((op_src)->slots_src, slot_name_src,                        \
343                        (op_dst)->slots_dst, slot_name_dst,                        \
344                        (op_dst)->arena)
345
346 void _bmo_slot_copy(
347         BMOpSlot slot_args_src[BMO_OP_MAX_SLOTS], const char *slot_name_src,
348         BMOpSlot slot_args_dst[BMO_OP_MAX_SLOTS], const char *slot_name_dst,
349         struct MemArena *arena_dst);
350
351 /* del "context" slot values, used for operator too */
352 enum {
353         DEL_VERTS = 1,
354         DEL_EDGES,
355         DEL_ONLYFACES,
356         DEL_EDGESFACES,
357         DEL_FACES,
358         /* A version of 'DEL_FACES' that keeps edges on face boundaries,
359          * allowing the surrounding edge-loop to be kept from removed face regions. */
360         DEL_FACES_KEEP_BOUNDARY,
361         DEL_ONLYTAGGED,
362 };
363
364 typedef enum {
365         BMO_SYMMETRIZE_NEGATIVE_X,
366         BMO_SYMMETRIZE_NEGATIVE_Y,
367         BMO_SYMMETRIZE_NEGATIVE_Z,
368
369         BMO_SYMMETRIZE_POSITIVE_X,
370         BMO_SYMMETRIZE_POSITIVE_Y,
371         BMO_SYMMETRIZE_POSITIVE_Z,
372 } BMO_SymmDirection;
373
374 typedef enum {
375         BMO_DELIM_NORMAL = 1 << 0,
376         BMO_DELIM_MATERIAL = 1 << 1,
377         BMO_DELIM_SEAM = 1 << 2,
378         BMO_DELIM_SHARP = 1 << 3,
379         BMO_DELIM_UV = 1 << 4,
380 } BMO_Delimit;
381
382 void BMO_op_flag_enable(BMesh *bm, BMOperator *op, const int op_flag);
383 void BMO_op_flag_disable(BMesh *bm, BMOperator *op, const int op_flag);
384
385 void  BMO_slot_float_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const float f);
386 float BMO_slot_float_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name);
387 void  BMO_slot_int_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const int i);
388 int   BMO_slot_int_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name);
389 void  BMO_slot_bool_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const bool i);
390 bool  BMO_slot_bool_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name);
391 void *BMO_slot_as_arrayN(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, int *len);
392
393
394 /* don't pass in arrays that are supposed to map to elements this way.
395  *
396  * so, e.g. passing in list of floats per element in another slot is bad.
397  * passing in, e.g. pointer to an editmesh for the conversion operator is fine
398  * though. */
399 void  BMO_slot_ptr_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, void *p);
400 void *BMO_slot_ptr_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name);
401 void  BMO_slot_vec_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const float vec[3]);
402 void  BMO_slot_vec_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, float r_vec[3]);
403
404 /* only supports square mats */
405 /* size must be 3 or 4; this api is meant only for transformation matrices.
406  * note that internally the matrix is stored in 4x4 form, and it's safe to
407  * call whichever BMO_Get_MatXXX function you want. */
408 void BMO_slot_mat_set(BMOperator *op, BMOpSlot slot_args[BMO_OP_MAX_SLOTS],  const char *slot_name, const float *mat, int size);
409 void BMO_slot_mat4_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, float r_mat[4][4]);
410 void BMO_slot_mat3_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, float r_mat[3][3]);
411
412 void BMO_mesh_flag_disable_all(BMesh *bm, BMOperator *op, const char htype, const short oflag);
413
414 void BMO_mesh_selected_remap(
415         BMesh *bm,
416         BMOpSlot *slot_vert_map,
417         BMOpSlot *slot_edge_map,
418         BMOpSlot *slot_face_map,
419         const bool check_select);
420
421 /* copies the values from another slot to the end of the output slot */
422 #define BMO_slot_buffer_append(op_src, slots_src, slot_name_src,              \
423                                op_dst, slots_dst, slot_name_dst)              \
424         _bmo_slot_buffer_append((op_src)->slots_src, slot_name_src,               \
425                                 (op_dst)->slots_dst, slot_name_dst,               \
426                                 (op_dst)->arena)
427 void _bmo_slot_buffer_append(
428         BMOpSlot slot_args_dst[BMO_OP_MAX_SLOTS], const char *slot_name_dst,
429         BMOpSlot slot_args_src[BMO_OP_MAX_SLOTS], const char *slot_name_src,
430         struct MemArena *arena_dst);
431
432 /* puts every element of type 'type' (which is a bitmask) with tool
433  * flag 'flag', into a slot. */
434 void BMO_slot_buffer_from_enabled_flag(
435         BMesh *bm, BMOperator *op,
436         BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
437         const char htype, const short oflag);
438
439 /* puts every element of type 'type' (which is a bitmask) without tool
440  * flag 'flag', into a slot. */
441 void BMO_slot_buffer_from_disabled_flag(
442         BMesh *bm, BMOperator *op,
443         BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
444         const char htype, const short oflag);
445
446 /* tool-flags all elements inside an element slot array with flag flag. */
447 void BMO_slot_buffer_flag_enable(
448         BMesh *bm,
449         BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
450         const char htype, const short oflag);
451 /* clears tool-flag flag from all elements inside a slot array. */
452 void BMO_slot_buffer_flag_disable(
453         BMesh *bm,
454         BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
455         const char htype, const short oflag);
456
457 /* tool-flags all elements inside an element slot array with flag flag. */
458 void BMO_slot_buffer_hflag_enable(
459         BMesh *bm,
460         BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
461         const char htype, const char hflag, const bool do_flush);
462 /* clears tool-flag flag from all elements inside a slot array. */
463 void BMO_slot_buffer_hflag_disable(
464         BMesh *bm,
465         BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
466         const char htype, const char hflag, const bool do_flush);
467
468 /* puts every element of type 'type' (which is a bitmask) with header
469  * flag 'flag', into a slot.  note: ignores hidden elements
470  * (e.g. elements with header flag BM_ELEM_HIDDEN set).*/
471 void BMO_slot_buffer_from_enabled_hflag(
472         BMesh *bm, BMOperator *op,
473         BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
474         const char htype, const char hflag);
475
476 /* puts every element of type 'type' (which is a bitmask) without
477  * header flag 'flag', into a slot.  note: ignores hidden elements
478  * (e.g. elements with header flag BM_ELEM_HIDDEN set).*/
479 void BMO_slot_buffer_from_disabled_hflag(
480         BMesh *bm, BMOperator *op,
481         BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
482         const char htype, const char hflag);
483
484 void  BMO_slot_buffer_from_array(BMOperator *op, BMOpSlot *slot, BMHeader **ele_buffer, int ele_buffer_len);
485
486 void  BMO_slot_buffer_from_single(BMOperator *op, BMOpSlot *slot, BMHeader *ele);
487 void *BMO_slot_buffer_get_single(BMOpSlot *slot);
488
489
490 /* counts number of elements inside a slot array. */
491 int BMO_slot_buffer_count(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name);
492 int BMO_slot_map_count(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name);
493
494 void BMO_slot_map_insert(
495         BMOperator *op, BMOpSlot *slot,
496         const void *element, const void *data);
497
498 /* flags all elements in a mapping.  note that the mapping must only have
499  * bmesh elements in it.*/
500 void BMO_slot_map_to_flag(
501         BMesh *bm, BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
502         const char *slot_name, const char hflag, const short oflag);
503
504 void *BMO_slot_buffer_alloc(
505         BMOperator *op, BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
506         const char *slot_name, const int len);
507
508 void BMO_slot_buffer_from_all(
509         BMesh *bm, BMOperator *op, BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
510         const char *slot_name, const char htype);
511
512 /**
513  * This part of the API is used to iterate over element buffer or
514  * mapping slots.
515  *
516  * for example, iterating over the faces in a slot is:
517  *
518  * \code{.c}
519  *
520  *    BMOIter oiter;
521  *    BMFace *f;
522  *
523  *    f = BMO_iter_new(&oiter, some_operator, "slot_name", BM_FACE);
524  *    for (; f; f = BMO_iter_step(&oiter)) {
525  *        // do something with the face
526  *    }
527  *
528  * another example, iterating over a mapping:
529  *    BMOIter oiter;
530  *    void *key;
531  *    void *val;
532  *
533  *    key = BMO_iter_new(&oiter, bm, some_operator, "slot_name", 0);
534  *    for (; key; key = BMO_iter_step(&oiter)) {
535  *        val = BMO_iter_map_value(&oiter);
536  *        //do something with the key/val pair
537  *        //note that val is a pointer to the val data,
538  *        //whether it's a float, pointer, whatever.
539  *        //
540  *        // so to get a pointer, for example, use:
541  *        //  *((void **)BMO_iter_map_value(&oiter));
542  *        //or something like that.
543  *    }
544  * \endcode
545  */
546
547 /* contents of this structure are private,
548  * don't directly access. */
549 typedef struct BMOIter {
550         BMOpSlot *slot;
551         int cur; //for arrays
552         GHashIterator giter;
553         void **val;
554         char restrictmask; /* bitwise '&' with BMHeader.htype */
555 } BMOIter;
556
557 void *BMO_slot_buffer_get_first(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name);
558
559 void *BMO_iter_new(
560         BMOIter *iter,
561         BMOpSlot slot_args[BMO_OP_MAX_SLOTS],  const char *slot_name,
562         const char restrictmask);
563 void *BMO_iter_step(BMOIter *iter);
564
565 void **BMO_iter_map_value_p(BMOIter *iter);
566 void  *BMO_iter_map_value_ptr(BMOIter *iter);
567
568 float BMO_iter_map_value_float(BMOIter *iter);
569 int   BMO_iter_map_value_int(BMOIter *iter);
570 bool  BMO_iter_map_value_bool(BMOIter *iter);
571
572 #define BMO_ITER(ele, iter, slot_args, slot_name, restrict_flag)   \
573         for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BMO_iter_new(iter, slot_args, slot_name, restrict_flag); \
574              ele; \
575              BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BMO_iter_step(iter))
576
577 #define BMO_ITER_INDEX(ele, iter, slot_args, slot_name, restrict_flag, i_)   \
578         for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BMO_iter_new(iter, slot_args, slot_name, restrict_flag), i_ = 0; \
579              ele; \
580              BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BMO_iter_step(iter), i_++)
581
582 extern const int BMO_OPSLOT_TYPEINFO[BMO_OP_SLOT_TOTAL_TYPES];
583
584 int BMO_opcode_from_opname(const char *opname);
585
586 #ifdef __cplusplus
587 }
588 #endif
589
590 #endif /* __BMESH_OPERATOR_API_H__ */