80f2856b0663686ecc31ce77acf5c8f60df28a55
[blender.git] / source / blender / bmesh / 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_memarena.h"
35 #include "BLI_ghash.h"
36
37 #include "BKE_utildefines.h"
38
39 #include <stdarg.h>
40 #include <string.h> /* for memcpy */
41
42 /*
43  * operators represent logical, executable mesh modules.  all topological
44  * operations involving a bmesh has to go through them.
45  *
46  * operators are nested, as are tool flags, which are private to an operator
47  * when it's executed.  tool flags are allocated in layers, one per operator
48  * execution, and are used for all internal flagging a tool needs to do.
49  *
50  * each operator has a series of "slots," which can be of the following types:
51  * - simple numerical types
52  * - arrays of elements (e.g. arrays of faces).
53  * - hash mappings.
54  *
55  * each slot is identified by a slot code, as are each operator.
56  * operators, and their slots, are defined in bmesh_opdefines.c (with their
57  * execution functions prototyped in bmesh_operators_private.h), with all their
58  * operator code and slot codes defined in bmesh_operators.h.  see
59  * bmesh_opdefines.c and the BMOpDefine struct for how to define new operators.
60  *
61  * in general, operators are fed arrays of elements, created using either
62  * BM_HeaderFlag_To_Slot or BM_Flag_To_Slot (or through one of the format
63  * specifyers in BMO_op_callf or BMO_op_initf).  Note that multiple element
64  * types (e.g. faces and edges) can be fed to the same slot array.  Operators
65  * act on this data, and possibly spit out data into output slots.
66  *
67  * some notes:
68  * - operators should never read from header flags (e.g. element->head.flag). for
69  *   example, if you want an operator to only operate on selected faces, you
70  *   should use BM_HeaderFlag_To_Slot to put the selected elements into a slot.
71  * - when you read from an element slot array or mapping, you can either tool-flag
72  *   all the elements in it, or read them using an iterator APi (which is
73  *   semantically similar to the iterator api in bmesh_iterators.h).
74  */
75
76 struct BMesh;
77 struct GHashIterator;
78
79 /* slot type arrays are terminated by the last member
80  * having a slot type of 0.*/
81 #define BMO_OP_SLOT_SENTINEL    0
82 #define BMO_OP_SLOT_BOOL                1
83 #define BMO_OP_SLOT_INT                 2
84 #define BMO_OP_SLOT_FLT                 3
85 #define BMO_OP_SLOT_PNT                 4
86 #define BMO_OP_SLOT_MAT                 5
87 #define BMO_OP_SLOT_VEC                 8
88
89 /* after BMO_OP_SLOT_VEC, everything is
90
91  * dynamically allocated arrays.  we
92  * leave a space in the identifiers
93  * for future growth.
94  */
95 //it's very important this remain a power of two
96 #define BMO_OP_SLOT_ELEMENT_BUF         9
97 #define BMO_OP_SLOT_MAPPING                     10
98 #define BMO_OP_SLOT_TOTAL_TYPES         11
99
100 /* please ignore all these structures, don't touch them in tool code, except
101  * for when your defining an operator with BMOpDefine.*/
102
103 typedef struct BMOpSlot{
104         int slottype;
105         int len;
106         int flag;
107         int index; /* index within slot array */
108         union {
109                 int i;
110                 float f;
111                 void *p;
112                 float vec[3];
113                 void *buf;
114                 GHash *ghash;
115         } data;
116 } BMOpSlot;
117
118 #define BMO_OP_MAX_SLOTS 16 /* way more than probably needed */
119
120 #ifdef slots
121 #undef slots
122 #endif
123
124 typedef struct BMOperator {
125         int type;
126         int slottype;
127         int needflag;
128         int flag;
129         struct BMOpSlot slots[BMO_OP_MAX_SLOTS];
130         void (*exec)(struct BMesh *bm, struct BMOperator *op);
131         MemArena *arena;
132 } BMOperator;
133
134 #define MAX_SLOTNAME    32
135
136 typedef struct BMOSlotType {
137         int type;
138         char name[MAX_SLOTNAME];
139 } BMOSlotType;
140
141 typedef struct BMOpDefine {
142         const char *name;
143         BMOSlotType slottypes[BMO_OP_MAX_SLOTS];
144         void (*exec)(BMesh *bm, BMOperator *op);
145         int flag;
146 } BMOpDefine;
147
148 /* BMOpDefine->flag */
149 #define BMO_OP_FLAG_UNTAN_MULTIRES              1 /*switch from multires tangent space to absolute coordinates*/
150
151 /* ensures consistent normals before operator execution,
152  * restoring the original ones windings/normals afterwards.
153  * keep in mind, this won't work if the input mesh isn't
154  * manifold.*/
155 #define BMO_OP_FLAG_RATIONALIZE_NORMALS 2
156
157 /*------------- Operator API --------------*/
158
159 /* data types that use pointers (arrays, etc) should never
160  * have it set directly.  and never use BMO_slot_ptr_set to
161  * pass in a list of edges or any arrays, really.*/
162
163 void BMO_op_init(struct BMesh *bm, struct BMOperator *op, const char *opname);
164
165 /* executes an operator, pushing and popping a new tool flag
166  * layer as appropriate.*/
167 void BMO_op_exec(struct BMesh *bm, struct BMOperator *op);
168
169 /* finishes an operator (though note the operator's tool flag is removed
170  * after it finishes executing in BMO_op_exec).*/
171 void BMO_op_finish(struct BMesh *bm, struct BMOperator *op);
172
173
174 /* tool flag API. never, ever ever should tool code put junk in
175  * header flags (element->head.flag), nor should they use
176  * element->head.eflag1/eflag2.  instead, use this api to set
177  * flags.
178  *
179  * if you need to store a value per element, use a
180  * ghash or a mapping slot to do it. */
181
182 /* flags 15 and 16 (1<<14 and 1<<15) are reserved for bmesh api use */
183 #define BMO_elem_flag_test(bm, element, oflag)    ((element)->oflags[bm->stackdepth-1].f &   (oflag))
184 #define BMO_elem_flag_enable(bm, element, oflag)  ((element)->oflags[bm->stackdepth-1].f |=  (oflag))
185 #define BMO_elem_flag_disable(bm, element, oflag) ((element)->oflags[bm->stackdepth-1].f &= ~(oflag))
186 #define BMO_elem_flag_set(bm, element, oflag, val)((val) ? BMO_elem_flag_enable(bm, element, oflag) : \
187                                                            BMO_elem_flag_disable(bm, element, oflag))
188 #define BMO_elem_flag_toggle(bm, element, oflag)  ((element)->oflags[bm->stackdepth-1].f ^=  (oflag))
189
190 /* count the number of elements with a specific flag.
191  * type can be a bitmask of BM_FACE, BM_EDGE, or BM_FACE. */
192 int BMO_mesh_flag_count(struct BMesh *bm, const short oflag, const char htype);
193
194 /*---------formatted operator initialization/execution-----------*/
195 /*
196  * this system is used to execute or initialize an operator,
197  * using a formatted-string system.
198  *
199  * for example, BMO_op_callf(bm, "del geom=%hf context=%i", BM_ELEM_SELECT, DEL_FACES);
200  * . . .will execute the delete operator, feeding in selected faces, deleting them.
201  *
202  * the basic format for the format string is:
203  *   [operatorname] [slotname]=%[code] [slotname]=%[code]
204  *
205  * as in printf, you pass in one additional argument to the function
206  * for every code.
207  *
208  * the formatting codes are:
209  *    %d - put int in slot
210  *    %f - put float in slot
211  *    %p - put pointer in slot
212  *    %h[f/e/v] - put elements with a header flag in slot.
213  *                 the letters after %h define which element types to use,
214  *             so e.g. %hf will do faces, %hfe will do faces and edges,
215  *             %hv will do verts, etc.  must pass in at least one
216  *             element type letter.
217  *    %f[f/e/v] - same as %h, except it deals with tool flags instead of
218  *                 header flags.
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_CallOpf in bmeshutils.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(struct BMOperator *op, const char *slotname);
247
248 /* get a pointer to a slot.  this may be removed layer on from the public API. */
249 BMOpSlot *BMO_slot_get(struct BMOperator *op, const char *slotname);
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(struct BMOperator *source_op, struct BMOperator *dest_op,
254                    const char *src, const char *dst);
255
256 /* remove tool flagged elements */
257 void BMO_remove_tagged_faces(struct BMesh *bm, const short oflag);
258 void BMO_remove_tagged_edges(struct BMesh *bm, const short oflag);
259 void BMO_remove_tagged_verts(struct BMesh *bm, const short oflag);
260
261 /* take care, uses operator flag DEL_WIREVERT */
262 void BMO_remove_tagged_context(BMesh *bm, const short oflag, const int type);
263
264 /* del "context" slot values, used for operator too */
265 enum {
266         DEL_VERTS = 1,
267         DEL_EDGES,
268         DEL_ONLYFACES,
269         DEL_EDGESFACES,
270         DEL_FACES,
271         DEL_ALL,
272         DEL_ONLYTAGGED
273 };
274
275 void BMO_op_flag_enable(struct BMesh *bm, struct BMOperator *op, const int op_flag);
276 void BMO_op_flag_disable(struct BMesh *bm, struct BMOperator *op, const int op_flag);
277
278 void  BMO_slot_float_set(struct BMOperator *op, const char *slotname, const float f);
279 float BMO_slot_float_get(BMOperator *op, const char *slotname);
280 void  BMO_slot_int_set(struct BMOperator *op, const char *slotname, const int i);
281 int   BMO_slot_int_get(BMOperator *op, const char *slotname);
282 void  BMO_slot_bool_set(struct BMOperator *op, const char *slotname, const int i);
283 int   BMO_slot_bool_get(BMOperator *op, const char *slotname);
284
285 /* don't pass in arrays that are supposed to map to elements this way.
286  *
287  * so, e.g. passing in list of floats per element in another slot is bad.
288  * passing in, e.g. pointer to an editmesh for the conversion operator is fine
289  * though. */
290 void  BMO_slot_ptr_set(struct BMOperator *op, const char *slotname, void *p);
291 void *BMO_slot_ptr_get(BMOperator *op, const char *slotname);
292 void  BMO_slot_vec_set(struct BMOperator *op, const char *slotname, const float vec[3]);
293 void  BMO_slot_vec_get(BMOperator *op, const char *slotname, float r_vec[3]);
294
295 /* only supports square mats */
296 /* size must be 3 or 4; this api is meant only for transformation matrices.
297  * note that internally the matrix is stored in 4x4 form, and it's safe to
298  * call whichever BMO_Get_Mat* function you want. */
299 void BMO_slot_mat_set(struct BMOperator *op, const char *slotname, const float *mat, int size);
300 void BMO_slot_mat4_get(struct BMOperator *op, const char *slotname, float r_mat[4][4]);
301 void BMO_slot_mat3_set(struct BMOperator *op, const char *slotname, float r_mat[3][3]);
302
303 void BMO_mesh_flag_disable_all(BMesh *bm, BMOperator *op, const char htype, const short oflag);
304
305 /* puts every element of type type (which is a bitmask) with tool flag flag,
306  * into a slot. */
307 void BMO_slot_from_flag(struct BMesh *bm, struct BMOperator *op, const char *slotname,
308                         const short oflag, const char htype);
309
310 /* tool-flags all elements inside an element slot array with flag flag. */
311 void BMO_slot_buffer_flag_enable(struct BMesh *bm, struct BMOperator *op, const char *slotname,
312                                  const short oflag, const char htype);
313 /* clears tool-flag flag from all elements inside a slot array. */
314 void BMO_slot_buffer_flag_disable(struct BMesh *bm, struct BMOperator *op, const char *slotname,
315                                   const short oflag, const char htype);
316
317 /* tool-flags all elements inside an element slot array with flag flag. */
318 void BMO_slot_buffer_hflag_enable(struct BMesh *bm, struct BMOperator *op, const char *slotname,
319                                   const char hflag, const char htype, char do_flush_select);
320 /* clears tool-flag flag from all elements inside a slot array. */
321 void BMO_slot_buffer_hflag_disable(struct BMesh *bm, struct BMOperator *op, const char *slotname,
322                                    const char hflag, const char htype, char do_flush_select);
323
324 /* puts every element of type type (which is a bitmask) with header flag
325  * flag, into a slot.  note: ignores hidden elements (e.g. elements with
326  * header flag BM_ELEM_HIDDEN set).*/
327 void BMO_slot_from_hflag(struct BMesh *bm, struct BMOperator *op, const char *slotname,
328                          const char hflag, const char htype);
329
330 /* counts number of elements inside a slot array. */
331 int BMO_slot_buf_count(struct BMesh *bm, struct BMOperator *op, const char *slotname);
332 int BMO_slot_map_count(struct BMesh *bm, struct BMOperator *op, const char *slotname);
333
334 /* Counts the number of edges with tool flag toolflag around
335  */
336 int BMO_vert_edge_flags_count(BMesh *bm, BMVert *v, const short oflag);
337
338 /* flags all elements in a mapping.  note that the mapping must only have
339  * bmesh elements in it.*/
340 void BMO_slot_map_to_flag(struct BMesh *bm, struct BMOperator *op,
341                           const char *slotname, const short oflag);
342
343 /* this part of the API is used to iterate over element buffer or
344  * mapping slots.
345  *
346  * for example, iterating over the faces in a slot is:
347  *
348  *    BMOIter oiter;
349  *    BMFace *f;
350  *
351  *    f = BMO_iter_new(&oiter, bm, some_operator, "slotname", BM_FACE);
352  *    for (; f; f=BMO_iter_step(&oiter)) {
353  *        /do something with the face
354  *    }
355  *
356  * another example, iterating over a mapping:
357  *    BMOIter oiter;
358  *    void *key;
359  *    void *val;
360  *
361  *    key = BMO_iter_new(&oiter, bm, some_operator, "slotname", 0);
362  *    for (; key; key=BMO_iter_step(&oiter)) {
363  *        val = BMO_iter_map_value(&oiter);
364  *        //do something with the key/val pair
365  *        //note that val is a pointer to the val data,
366  *        //whether it's a float, pointer, whatever.
367  *        //
368  *        // so to get a pointer, for example, use:
369  *        //  *((void**)BMO_iter_map_value(&oiter));
370  *        //or something like that.
371  *    }
372  */
373
374 /* contents of this structure are private,
375  * don't directly access. */
376 typedef struct BMOIter {
377         BMOpSlot *slot;
378         int cur; //for arrays
379         struct GHashIterator giter;
380         void *val;
381         char restrictmask; /* bitwise '&' with BMHeader.htype */
382 } BMOIter;
383
384 void *BMO_slot_elem_first(BMOperator *op, const char *slotname);
385
386 /* restrictmask restricts the iteration to certain element types
387  * (e.g. combination of BM_VERT, BM_EDGE, BM_FACE), if iterating
388  * over an element buffer (not a mapping).*/
389 void *BMO_iter_new(BMOIter *iter, BMesh *bm, BMOperator *op,
390                    const char *slotname, const char restrictmask);
391 void *BMO_iter_step(BMOIter *iter);
392
393 /* returns a pointer to the key value when iterating over mappings.
394  * remember for pointer maps this will be a pointer to a pointer.*/
395 void *BMO_iter_map_value(BMOIter *iter);
396
397 /* use this for pointer mappings */
398 void *BMO_iter_map_value_p(BMOIter *iter);
399
400 /* use this for float mappings */
401 float BMO_iter_map_value_f(BMOIter *iter);
402
403 #define BMO_ITER(ele, iter, bm, op, slotname, restrict)   \
404         ele = BMO_iter_new(iter, bm, op, slotname, restrict); \
405         for ( ; ele; ele=BMO_iter_step(iter))
406
407 /******************* Inlined Functions********************/
408 typedef void (*opexec)(struct BMesh *bm, struct BMOperator *op);
409
410 /* mappings map elements to data, which
411  * follows the mapping struct in memory. */
412 typedef struct BMOElemMapping {
413         BMHeader *element;
414         int len;
415 } BMOElemMapping;
416
417 extern const int BMO_OPSLOT_TYPEINFO[BMO_OP_SLOT_TOTAL_TYPES];
418
419 #ifdef __cplusplus
420 }
421 #endif
422
423 #endif /* __BMESH_OPERATOR_API_H__ */