c6dd33b7a4b90b9cca9c4ec406991c3bbff59015
[blender.git] / source / blender / bmesh / intern / bmesh_operator_api.h
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
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.
8  *
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.
13  *
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.
17  *
18  * Contributor(s): Joseph Eagar.
19  *
20  * ***** END GPL LICENSE BLOCK *****
21  */
22
23 #ifndef __BMESH_OPERATOR_API_H__
24 #define __BMESH_OPERATOR_API_H__
25
26 /** \file blender/bmesh/bmesh_operator_api.h
27  *  \ingroup bmesh
28  */
29
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33
34 #include "BLI_ghash.h"
35
36 #include <stdarg.h>
37
38 /**
39  * operators represent logical, executable mesh modules.  all topological
40  * operations involving a bmesh has to go through them.
41  *
42  * operators are nested, as are tool flags, which are private to an operator
43  * when it's executed.  tool flags are allocated in layers, one per operator
44  * execution, and are used for all internal flagging a tool needs to do.
45  *
46  * each operator has a series of "slots" which can be of the following types:
47  * - simple numerical types
48  * - arrays of elements (e.g. arrays of faces).
49  * - hash mappings.
50  *
51  * each slot is identified by a slot code, as are each operator.
52  * operators, and their slots, are defined in bmesh_opdefines.c (with their
53  * execution functions prototyped in bmesh_operators_private.h), with all their
54  * operator code and slot codes defined in bmesh_operators.h.  see
55  * bmesh_opdefines.c and the BMOpDefine struct for how to define new operators.
56  *
57  * in general, operators are fed arrays of elements, created using either
58  * #BMO_slot_buffer_from_hflag or #BMO_slot_buffer_from_flag
59  * (or through one of the format specifiers in #BMO_op_callf or #BMO_op_initf).
60  *
61  * \note multiple element types (e.g. faces and edges)
62  * can be fed to the same slot array.  Operators act on this data,
63  * and possibly spit out data into output slots.
64  *
65  * \note operators should never read from header flags (e.g. element->head.flag).
66  * For example, if you want an operator to only operate on selected faces, you
67  * should use #BMO_slot_buffer_from_hflag to put the selected elements into a slot.
68  *
69  * \note when you read from an element slot array or mapping, you can either tool-flag
70  * all the elements in it, or read them using an iterator API (which is semantically
71  * similar to the iterator api in bmesh_iterators.h).
72  *
73  * \note only #BMLoop items can't be put into slots as with verts, edges & faces.
74  */
75
76 struct GHashIterator;
77
78 #define BMO_elem_flag_test(     bm, ele, oflag)      _bmo_elem_flag_test     (bm, (ele)->oflags, oflag)
79 #define BMO_elem_flag_test_bool(bm, ele, oflag)      _bmo_elem_flag_test_bool(bm, (ele)->oflags, oflag)
80 #define BMO_elem_flag_enable(   bm, ele, oflag)      _bmo_elem_flag_enable   (bm, (ele)->oflags, oflag)
81 #define BMO_elem_flag_disable(  bm, ele, oflag)      _bmo_elem_flag_disable  (bm, (ele)->oflags, oflag)
82 #define BMO_elem_flag_set(      bm, ele, oflag, val) _bmo_elem_flag_set      (bm, (ele)->oflags, oflag, val)
83 #define BMO_elem_flag_toggle(   bm, ele, oflag)      _bmo_elem_flag_toggle   (bm, (ele)->oflags, oflag)
84
85 BLI_INLINE short _bmo_elem_flag_test(     BMesh *bm, BMFlagLayer *oflags, const short oflag);
86 BLI_INLINE short _bmo_elem_flag_test_bool(BMesh *bm, BMFlagLayer *oflags, const short oflag);
87 BLI_INLINE void  _bmo_elem_flag_enable(   BMesh *bm, BMFlagLayer *oflags, const short oflag);
88 BLI_INLINE void  _bmo_elem_flag_disable(  BMesh *bm, BMFlagLayer *oflags, const short oflag);
89 BLI_INLINE void  _bmo_elem_flag_set(      BMesh *bm, BMFlagLayer *oflags, const short oflag, int val);
90 BLI_INLINE void  _bmo_elem_flag_toggle(   BMesh *bm, BMFlagLayer *oflags, const short oflag);
91
92 /* slot type arrays are terminated by the last member
93  * having a slot type of 0 */
94 enum {
95         BMO_OP_SLOT_SENTINEL = 0,
96         BMO_OP_SLOT_BOOL = 1,
97         BMO_OP_SLOT_INT = 2,
98         BMO_OP_SLOT_FLT = 3,
99
100         /* normally store pointers to object, scene,
101          * _never_ store arrays corresponding to mesh elements with this */
102         BMO_OP_SLOT_PNT = 4,
103         BMO_OP_SLOT_MAT = 5,
104         BMO_OP_SLOT_VEC = 8,
105
106         /* after BMO_OP_SLOT_VEC, everything is dynamically allocated arrays.
107          * We leave a space in the identifiers for future growth.
108          *
109          * it's very important this remain a power of two */
110         BMO_OP_SLOT_ELEMENT_BUF = 9, /* list of verts/edges/faces */
111         BMO_OP_SLOT_MAPPING = 10 /* simple hash map */
112 };
113 #define BMO_OP_SLOT_TOTAL_TYPES 11
114
115 /* please ignore all these structures, don't touch them in tool code, except
116  * for when your defining an operator with BMOpDefine.*/
117
118 typedef struct BMOpSlot {
119         int slot_type;
120         int len;
121         int flag;
122         int index; /* index within slot array */
123         union {
124                 int i;
125                 float f;
126                 void *p;
127                 float vec[3];
128                 void *buf;
129                 GHash *ghash;
130         } data;
131 } BMOpSlot;
132
133 #define BMO_OP_MAX_SLOTS 16 /* way more than probably needed */
134
135 typedef struct BMOperator {
136         int type;
137         int slot_type;
138         int needflag;
139         int flag;
140         struct BMOpSlot slot_args[BMO_OP_MAX_SLOTS];
141         void (*exec)(BMesh *bm, struct BMOperator *op);
142         struct MemArena *arena;
143 } BMOperator;
144
145 #define MAX_SLOTNAME    32
146
147 typedef struct BMOSlotType {
148         int type;
149         char name[MAX_SLOTNAME];
150 } BMOSlotType;
151
152 typedef struct BMOpDefine {
153         const char *name;
154         BMOSlotType slot_types[BMO_OP_MAX_SLOTS];
155         void (*exec)(BMesh *bm, BMOperator *op);
156         int flag;
157 } BMOpDefine;
158
159 /* BMOpDefine->flag */
160 #define BMO_OP_FLAG_UNTAN_MULTIRES              1 /*switch from multires tangent space to absolute coordinates*/
161
162 /* ensures consistent normals before operator execution,
163  * restoring the original ones windings/normals afterwards.
164  * keep in mind, this won't work if the input mesh isn't
165  * manifold.*/
166 #define BMO_OP_FLAG_RATIONALIZE_NORMALS 2
167
168 /*------------- Operator API --------------*/
169
170 /* data types that use pointers (arrays, etc) should never
171  * have it set directly.  and never use BMO_slot_ptr_set to
172  * pass in a list of edges or any arrays, really.*/
173
174 void BMO_op_init(BMesh *bm, BMOperator *op, const char *opname);
175
176 /* executes an operator, pushing and popping a new tool flag
177  * layer as appropriate.*/
178 void BMO_op_exec(BMesh *bm, BMOperator *op);
179
180 /* finishes an operator (though note the operator's tool flag is removed
181  * after it finishes executing in BMO_op_exec).*/
182 void BMO_op_finish(BMesh *bm, BMOperator *op);
183
184 /* count the number of elements with the specified flag enabled.
185  * type can be a bitmask of BM_FACE, BM_EDGE, or BM_FACE. */
186 int BMO_mesh_enabled_flag_count(BMesh *bm, const char htype, const short oflag);
187
188 /* count the number of elements with the specified flag disabled.
189  * type can be a bitmask of BM_FACE, BM_EDGE, or BM_FACE. */
190 int BMO_mesh_disabled_flag_count(BMesh *bm, const char htype, const short oflag);
191
192 /*---------formatted operator initialization/execution-----------*/
193 /*
194  * this system is used to execute or initialize an operator,
195  * using a formatted-string system.
196  *
197  * for example, BMO_op_callf(bm, "del geom=%hf context=%i", BM_ELEM_SELECT, DEL_FACES);
198  * . . .will execute the delete operator, feeding in selected faces, deleting them.
199  *
200  * the basic format for the format string is:
201  *   [operatorname] [slot_name]=%[code] [slot_name]=%[code]
202  *
203  * as in printf, you pass in one additional argument to the function
204  * for every code.
205  *
206  * the formatting codes are:
207  *    %d - put int in slot
208  *    %f - put float in slot
209  *    %p - put pointer in slot
210  *    %h[f/e/v] - put elements with a header flag in slot.
211  *                 the letters after %h define which element types to use,
212  *             so e.g. %hf will do faces, %hfe will do faces and edges,
213  *             %hv will do verts, etc.  must pass in at least one
214  *             element type letter.
215  *    %H[f/e/v] - same as %h, but tests if the flag is disabled
216  *    %f[f/e/v] - same as %h, except it deals with tool flags instead of
217  *                 header flags.
218  *    %F[f/e/v] - same as %f, but tests if the flag is disabled
219  *    %a[f/e/v] - pass all elements (of types specified by f/e/v) to the
220  *                 slot.
221  *    %e        - pass in a single element.
222  *    %v - pointer to a float vector of length 3.
223  *    %m[3/4] - matrix, 3/4 refers to the matrix size, 3 or 4.  the
224  *              corresponding argument must be a pointer to
225  *          a float matrix.
226  *    %s - copy a slot from another op, instead of mapping to one
227  *         argument, it maps to two, a pointer to an operator and
228  *     a slot name.
229  */
230 void BMO_push(BMesh *bm, BMOperator *op);
231 void BMO_pop(BMesh *bm);
232
233 /*executes an operator*/
234 int BMO_op_callf(BMesh *bm, const char *fmt, ...);
235
236 /* initializes, but doesn't execute an operator.  this is so you can
237  * gain access to the outputs of the operator.  note that you have
238  * to execute/finitsh (BMO_op_exec and BMO_op_finish) yourself. */
239 int BMO_op_initf(BMesh *bm, BMOperator *op, const char *fmt, ...);
240
241 /* va_list version, used to implement the above two functions,
242  * plus EDBM_op_callf in editmesh_utils.c. */
243 int BMO_op_vinitf(BMesh *bm, BMOperator *op, const char *fmt, va_list vlist);
244
245 /* test whether a named slot exists */
246 int BMO_slot_exists(BMOperator *op, const char *slot_name);
247
248 /* get a pointer to a slot.  this may be removed layer on from the public API. */
249 BMOpSlot *BMO_slot_get(BMOperator *op, const char *slot_name);
250
251 /* copies the data of a slot from one operator to another.  src and dst are the
252  * source/destination slot codes, respectively. */
253 void BMO_slot_copy(BMOperator *source_op, BMOperator *dest_op,
254                    const char *src, const char *dst);
255
256 /* del "context" slot values, used for operator too */
257 enum {
258         DEL_VERTS = 1,
259         DEL_EDGES,
260         DEL_ONLYFACES,
261         DEL_EDGESFACES,
262         DEL_FACES,
263         DEL_ALL,
264         DEL_ONLYTAGGED
265 };
266
267 void BMO_op_flag_enable(BMesh *bm, BMOperator *op, const int op_flag);
268 void BMO_op_flag_disable(BMesh *bm, BMOperator *op, const int op_flag);
269
270 void  BMO_slot_float_set(BMOperator *op, const char *slot_name, const float f);
271 float BMO_slot_float_get(BMOperator *op, const char *slot_name);
272 void  BMO_slot_int_set(BMOperator *op, const char *slot_name, const int i);
273 int   BMO_slot_int_get(BMOperator *op, const char *slot_name);
274 void  BMO_slot_bool_set(BMOperator *op, const char *slot_name, const int i);
275 int   BMO_slot_bool_get(BMOperator *op, const char *slot_name);
276
277 /* don't pass in arrays that are supposed to map to elements this way.
278  *
279  * so, e.g. passing in list of floats per element in another slot is bad.
280  * passing in, e.g. pointer to an editmesh for the conversion operator is fine
281  * though. */
282 void  BMO_slot_ptr_set(BMOperator *op, const char *slot_name, void *p);
283 void *BMO_slot_ptr_get(BMOperator *op, const char *slot_name);
284 void  BMO_slot_vec_set(BMOperator *op, const char *slot_name, const float vec[3]);
285 void  BMO_slot_vec_get(BMOperator *op, const char *slot_name, float r_vec[3]);
286
287 /* only supports square mats */
288 /* size must be 3 or 4; this api is meant only for transformation matrices.
289  * note that internally the matrix is stored in 4x4 form, and it's safe to
290  * call whichever BMO_Get_Mat* function you want. */
291 void BMO_slot_mat_set(BMOperator *op, const char *slot_name, const float *mat, int size);
292 void BMO_slot_mat4_get(BMOperator *op, const char *slot_name, float r_mat[4][4]);
293 void BMO_slot_mat3_set(BMOperator *op, const char *slot_name, float r_mat[3][3]);
294
295 void BMO_mesh_flag_disable_all(BMesh *bm, BMOperator *op, const char htype, const short oflag);
296
297 /* copies the values from another slot to the end of the output slot */
298 void BMO_slot_buffer_append(BMOperator *output_op, const char *output_op_slot,
299                             BMOperator *other_op, const char *other_op_slot);
300
301 /* puts every element of type 'type' (which is a bitmask) with tool
302  * flag 'flag', into a slot. */
303 void BMO_slot_buffer_from_enabled_flag(BMesh *bm, BMOperator *op, const char *slot_name,
304                                        const char htype, const short oflag);
305
306 /* puts every element of type 'type' (which is a bitmask) without tool
307  * flag 'flag', into a slot. */
308 void BMO_slot_buffer_from_disabled_flag(BMesh *bm, BMOperator *op, const char *slot_name,
309                                         const char htype, const short oflag);
310
311 /* tool-flags all elements inside an element slot array with flag flag. */
312 void BMO_slot_buffer_flag_enable(BMesh *bm, BMOperator *op, const char *slot_name,
313                                  const char htype, const short oflag);
314 /* clears tool-flag flag from all elements inside a slot array. */
315 void BMO_slot_buffer_flag_disable(BMesh *bm, BMOperator *op, const char *slot_name,
316                                   const char htype, const short oflag);
317
318 /* tool-flags all elements inside an element slot array with flag flag. */
319 void BMO_slot_buffer_hflag_enable(BMesh *bm, BMOperator *op, const char *slot_name,
320                                   const char htype, const char hflag, const char do_flush);
321 /* clears tool-flag flag from all elements inside a slot array. */
322 void BMO_slot_buffer_hflag_disable(BMesh *bm, BMOperator *op, const char *slot_name,
323                                    const char htype, const char hflag, const char do_flush);
324
325 /* puts every element of type 'type' (which is a bitmask) with header
326  * flag 'flag', into a slot.  note: ignores hidden elements
327  * (e.g. elements with header flag BM_ELEM_HIDDEN set).*/
328 void BMO_slot_buffer_from_enabled_hflag(BMesh *bm, BMOperator *op,
329                                         const char *slot_name,
330                                         const char htype, const char hflag);
331
332 /* puts every element of type 'type' (which is a bitmask) without
333  * header flag 'flag', into a slot.  note: ignores hidden elements
334  * (e.g. elements with header flag BM_ELEM_HIDDEN set).*/
335 void BMO_slot_buffer_from_disabled_hflag(BMesh *bm, BMOperator *op,
336                                          const char *slot_name,
337                                          const char htype, const char hflag);
338
339 /* counts number of elements inside a slot array. */
340 int BMO_slot_buffer_count(BMesh *bm, BMOperator *op, const char *slot_name);
341 int BMO_slot_map_count(BMesh *bm, BMOperator *op, const char *slot_name);
342
343 void BMO_slot_map_insert(BMesh *UNUSED(bm), BMOperator *op, const char *slot_name,
344                          void *element, void *data, int len);
345
346 /* Counts the number of edges with tool flag toolflag around
347  */
348 int BMO_vert_edge_flags_count(BMesh *bm, BMVert *v, const short oflag);
349
350 /* flags all elements in a mapping.  note that the mapping must only have
351  * bmesh elements in it.*/
352 void BMO_slot_map_to_flag(BMesh *bm, BMOperator *op, const char *slot_name,
353                           const char hflag, const short oflag);
354
355 void BMO_slot_buffer_from_all(BMesh *bm, BMOperator *op, const char *slot_name,
356                               const char htype);
357
358 /* this part of the API is used to iterate over element buffer or
359  * mapping slots.
360  *
361  * for example, iterating over the faces in a slot is:
362  *
363  *    BMOIter oiter;
364  *    BMFace *f;
365  *
366  *    f = BMO_iter_new(&oiter, bm, some_operator, "slot_name", BM_FACE);
367  *    for (; f; f = BMO_iter_step(&oiter)) {
368  *        /do something with the face
369  *    }
370  *
371  * another example, iterating over a mapping:
372  *    BMOIter oiter;
373  *    void *key;
374  *    void *val;
375  *
376  *    key = BMO_iter_new(&oiter, bm, some_operator, "slot_name", 0);
377  *    for (; key; key = BMO_iter_step(&oiter)) {
378  *        val = BMO_iter_map_value(&oiter);
379  *        //do something with the key/val pair
380  *        //note that val is a pointer to the val data,
381  *        //whether it's a float, pointer, whatever.
382  *        //
383  *        // so to get a pointer, for example, use:
384  *        //  *((void**)BMO_iter_map_value(&oiter));
385  *        //or something like that.
386  *    }
387  */
388
389 /* contents of this structure are private,
390  * don't directly access. */
391 typedef struct BMOIter {
392         BMOpSlot *slot;
393         int cur; //for arrays
394         GHashIterator giter;
395         void *val;
396         char restrictmask; /* bitwise '&' with BMHeader.htype */
397 } BMOIter;
398
399 void *BMO_slot_buffer_elem_first(BMOperator *op, const char *slot_name);
400
401 void *BMO_iter_new(BMOIter *iter, BMesh *bm, BMOperator *op,
402                    const char *slot_name, const char restrictmask);
403 void *BMO_iter_step(BMOIter *iter);
404
405 /* returns a pointer to the key value when iterating over mappings.
406  * remember for pointer maps this will be a pointer to a pointer.*/
407 void *BMO_iter_map_value(BMOIter *iter);
408
409 /* use this for pointer mappings */
410 void *BMO_iter_map_value_p(BMOIter *iter);
411
412 /* use this for float mappings */
413 float BMO_iter_map_value_f(BMOIter *iter);
414
415 #define BMO_ITER(ele, iter, bm, op, slot_name, restrict)   \
416         for (ele = BMO_iter_new(iter, bm, op, slot_name, restrict); ele; ele = BMO_iter_step(iter))
417
418 /******************* Inlined Functions********************/
419 typedef void (*opexec)(BMesh *bm, BMOperator *op);
420
421 /* mappings map elements to data, which
422  * follows the mapping struct in memory. */
423 typedef struct BMOElemMapping {
424         BMHeader *element;
425         int len;
426 } BMOElemMapping;
427
428 extern const int BMO_OPSLOT_TYPEINFO[BMO_OP_SLOT_TOTAL_TYPES];
429
430 #ifdef __cplusplus
431 }
432 #endif
433
434 #endif /* __BMESH_OPERATOR_API_H__ */