7d1513e0b80b0767fb31878a1ab7b80f38f745a6
[blender.git] / source / blender / bmesh / bmesh_operator_api.h
1 #ifndef _BMESH_OPERATOR_H
2 #define _BMESH_OPERATOR_H
3
4 #include "BLI_memarena.h"
5 #include "BLI_ghash.h"
6
7 #include <stdarg.h>
8
9 /*
10 operators represent logical, executable mesh modules.  all topological 
11 operations involving a bmesh has to go through them.
12
13 operators are nested, as are tool flags, which are private to an operator 
14 when it's executed.  tool flags are allocated in layers, one per operator
15 execution, and are used for all internal flagging a tool needs to do.
16
17 each operator has a series of "slots," which can be of the following types:
18 * simple numerical types
19 * arrays of elements (e.g. arrays of faces).
20 * hash mappings.
21
22 each slot is identified by a slot code, as are each operator. 
23 operators, and their slots, are defined in bmesh_opdefines.c (with their 
24 execution functions prototyped in bmesh_operators_private.h), with all their
25 operator code and slot codes defined in bmesh_operators.h.  see
26 bmesh_opdefines.c and the BMOpDefine struct for how to define new operators.
27
28 in general, operators are fed arrays of elements, created using either
29 BM_HeaderFlag_To_Slot or BM_Flag_To_Slot (or through one of the format
30 specifyers in BMO_CallOpf or BMO_InitOpf).  Note that multiple element
31 types (e.g. faces and edges) can be fed to the same slot array.  Operators
32 act on this data, and possibly spit out data into output slots.
33
34 some notes:
35 * operators should never read from header flags (e.g. element->head.flag). for
36   example, if you want an operator to only operate on selected faces, you
37   should use BM_HeaderFlag_To_Slot to put the selected elements into a slot.
38 * when you read from an element slot array or mapping, you can either tool-flag 
39   all the elements in it, or read them using an iterator APi (which is 
40   semantically similar to the iterator api in bmesh_iterators.h).
41 */
42
43 struct GHashIterator;
44
45 /*slot type arrays are terminated by the last member
46   having a slot type of 0.*/
47 #define BMOP_OPSLOT_SENTINEL            0
48 #define BMOP_OPSLOT_INT                 1
49 #define BMOP_OPSLOT_FLT                 2
50 #define BMOP_OPSLOT_PNT                 3
51 #define BMOP_OPSLOT_MAT                 4
52 #define BMOP_OPSLOT_VEC                 7
53
54 /*after BMOP_OPSLOT_VEC, everything is 
55
56   dynamically allocated arrays.  we
57   leave a space in the identifiers
58   for future growth.
59
60   */
61 //it's very important this remain a power of two
62 #define BMOP_OPSLOT_ELEMENT_BUF         8
63 #define BMOP_OPSLOT_MAPPING             9
64 #define BMOP_OPSLOT_TYPES               10
65
66 /*please ignore all these structures, don't touch them in tool code, except
67   for when your defining an operator with BMOpDefine.*/
68
69 typedef struct BMOpSlot{
70         int slottype;
71         int len;
72         int flag;
73         int index; /*index within slot array*/
74         union {
75                 int i;
76                 float f;                                        
77                 void *p;                                        
78                 float vec[3];
79                 void *buf;
80                 GHash *ghash;
81         } data;
82 }BMOpSlot;
83
84 #define BMOP_MAX_SLOTS                  16 /*way more than probably needed*/
85
86 typedef struct BMOperator {
87         int type;
88         int slottype;
89         int needflag;
90         struct BMOpSlot slots[BMOP_MAX_SLOTS];
91         void (*exec)(struct BMesh *bm, struct BMOperator *op);
92         MemArena *arena;
93 } BMOperator;
94
95 #define MAX_SLOTNAME    32
96
97 typedef struct slottype {
98         int type;
99         char name[MAX_SLOTNAME];
100 } slottype;
101
102 typedef struct BMOpDefine {
103         char *name;
104         slottype slottypes[BMOP_MAX_SLOTS];
105         void (*exec)(BMesh *bm, BMOperator *op);
106         int flag; /*doesn't do anything right now*/
107 } BMOpDefine;
108
109 /*------------- Operator API --------------*/
110
111 /*data types that use pointers (arrays, etc) should never
112   have it set directly.  and never use BMO_Set_Pnt to
113   pass in a list of edges or any arrays, really.*/
114
115 void BMO_Init_Op(struct BMOperator *op, char *opname);
116
117 /*executes an operator, pushing and popping a new tool flag 
118   layer as appropriate.*/
119 void BMO_Exec_Op(struct BMesh *bm, struct BMOperator *op);
120
121 /*finishes an operator (though note the operator's tool flag is removed 
122   after it finishes executing in BMO_Exec_Op).*/
123 void BMO_Finish_Op(struct BMesh *bm, struct BMOperator *op);
124
125
126 /*tool flag API. never, ever ever should tool code put junk in 
127   header flags (element->head.flag), nor should they use 
128   element->head.eflag1/eflag2.  instead, use this api to set
129   flags.  
130   
131   if you need to store a value per element, use a 
132   ghash or a mapping slot to do it.*/
133 /*flags 15 and 16 (1<<14 and 1<<15) are reserved for bmesh api use*/
134 void BMO_SetFlag(struct BMesh *bm, void *element, int flag);
135 void BMO_ClearFlag(struct BMesh *bm, void *element, int flag);
136 int BMO_TestFlag(struct BMesh *bm, void *element, int flag);
137
138 /*count the number of elements with a specific flag.  type
139   can be a bitmask of BM_FACE, BM_EDGE, or BM_FACE.*/
140 int BMO_CountFlag(struct BMesh *bm, int flag, int type);
141
142 /*---------formatted operator initialization/execution-----------*/
143 /*
144   this system is used to execute or initialize an operator,
145   using a formatted-string system.
146
147   for example, BMO_CallOpf(bm, "del geom=%hf context=%d", BM_SELECT, DEL_FACES);
148   . . .will execute the delete operator, feeding in selected faces, deleting them.
149
150   the basic format for the format string is:
151     [operatorname] [slotname]=%[code] [slotname]=%[code]
152   
153   as in printf, you pass in one additional argument to the function
154   for every code.
155
156   the formatting codes are:
157      %d - put int in slot
158      %f - put float in slot
159      %p - put pointer in slot
160      %h[f/e/v] - put elements with a header flag in slot.
161           the letters after %h define which element types to use,
162           so e.g. %hf will do faces, %hfe will do faces and edges,
163           %hv will do verts, etc.  must pass in at least one
164           element type letter.
165      %f[f/e/v] - same as %h, except it deals with tool flags instead of
166                   header flags.
167      %a[f/e/v] - pass all elements (of types specified by f/e/v) to the
168                  slot.
169      %v - pointer to a float vector of length 3.
170      %m[3/4] - matrix, 3/4 refers to the matrix size, 3 or 4.  the
171                corrusponding argument must be a pointer to
172                a float matrix.
173      %s - copy a slot from another op, instead of mapping to one
174           argument, it maps to two, a pointer to an operator and
175           a slot name.
176 */
177 /*executes an operator*/
178 int BMO_CallOpf(BMesh *bm, char *fmt, ...);
179
180 /*initializes, but doesn't execute an operator.  this is so you can
181   gain access to the outputs of the operator.  note that you have
182   to execute/finitsh (BMO_Exec_Op and BMO_Finish_Op) yourself.*/
183 int BMO_InitOpf(BMesh *bm, BMOperator *op, char *fmt, ...);
184
185 /*va_list version, used to implement the above two functions,
186    plus EDBM_CallOpf in bmeshutils.c.*/
187 int BMO_VInitOpf(BMesh *bm, BMOperator *op, char *fmt, va_list vlist);
188
189 /*get a point to a slot.  this may be removed layer on from the public API.*/
190 BMOpSlot *BMO_GetSlot(struct BMOperator *op, char *slotname);
191
192 /*copies the data of a slot from one operator to another.  src and dst are the
193   source/destination slot codes, respectively.*/
194 void BMO_CopySlot(struct BMOperator *source_op, struct BMOperator *dest_op, 
195                   char *src, char *dst);
196
197
198 void BMO_Set_Float(struct BMOperator *op, char *slotname, float f);
199 float BMO_Get_Float(BMOperator *op, char *slotname);
200 void BMO_Set_Int(struct BMOperator *op, char *slotname, int i);
201 int BMO_Get_Int(BMOperator *op, char *slotname);
202
203 /*don't pass in arrays that are supposed to map to elements this way.
204   
205   so, e.g. passing in list of floats per element in another slot is bad.
206   passing in, e.g. pointer to an editmesh for the conversion operator is fine
207   though.*/
208 void BMO_Set_Pnt(struct BMOperator *op, char *slotname, void *p);
209 void *BMO_Get_Pnt(BMOperator *op, char *slotname);
210 void BMO_Set_Vec(struct BMOperator *op, char *slotname, float *vec);
211 void BMO_Get_Vec(BMOperator *op, char *slotname, float *vec_out);
212
213 /*only supports square mats*/
214 /*size must be 3 or 4; this api is meant only for transformation matrices.
215   note that internally the matrix is stored in 4x4 form, and it's safe to
216   call whichever BMO_Get_Mat* function you want.*/
217 void BMO_Set_Mat(struct BMOperator *op, char *slotname, float *mat, int size);
218 void BMO_Get_Mat4(struct BMOperator *op, char *slotname, float mat[4][4]);
219 void BMO_Get_Mat3(struct BMOperator *op, char *slotname, float mat[3][3]);
220
221 /*puts every element of type type (which is a bitmask) with tool flag flag,
222   into a slot.*/
223 void BMO_Flag_To_Slot(struct BMesh *bm, struct BMOperator *op, char *slotname, int flag, int type);
224
225 /*tool-flags all elements inside an element slot array with flag flag.*/
226 void BMO_Flag_Buffer(struct BMesh *bm, struct BMOperator *op, char *slotname, int flag);
227 /*clears tool-flag flag from all elements inside a slot array.*/
228 void BMO_Unflag_Buffer(struct BMesh *bm, struct BMOperator *op, char *slotname, int flag);
229
230 /*tool-flags all elements inside an element slot array with flag flag.*/
231 void BMO_HeaderFlag_Buffer(struct BMesh *bm, struct BMOperator *op, char *slotname, int flag);
232 /*clears tool-flag flag from all elements inside a slot array.*/
233 void BMO_UnHeaderFlag_Buffer(struct BMesh *bm, struct BMOperator *op, char *slotname, int flag);
234
235 /*puts every element of type type (which is a bitmask) with header flag 
236   flag, into a slot.*/
237 void BMO_HeaderFlag_To_Slot(struct BMesh *bm, struct BMOperator *op, char *slotname, int flag, int type);
238
239 /*counts number of elements inside a slot array.*/
240 int BMO_CountSlotBuf(struct BMesh *bm, struct BMOperator *op, char *slotname);
241
242
243 /*inserts a key/value mapping into a mapping slot.  note that it copies the
244   value, it doesn't store a reference to it.*/
245 void BMO_Insert_Mapping(BMesh *bm, BMOperator *op, char *slotname, 
246                         void *element, void *data, int len);
247
248 /*inserts a key/float mapping pair into a mapping slot.*/
249 void BMO_Insert_MapFloat(BMesh *bm, BMOperator *op, char *slotname, 
250                         void *element, float val);
251
252 //returns 1 if the specified pointer is in the map.
253 int BMO_InMap(BMesh *bm, BMOperator *op, char *slotname, void *element);
254
255 /*returns a point to the value of a specific key.*/
256 void *BMO_Get_MapData(BMesh *bm, BMOperator *op, char *slotname, void *element);
257
258 /*returns the float part of a key/float pair.*/
259 float BMO_Get_MapFloat(BMesh *bm, BMOperator *op, char *slotname, void *element);
260
261 /*flags all elements in a mapping.  note that the mapping must only have
262   bmesh elements in it.*/
263 void BMO_Mapping_To_Flag(struct BMesh *bm, struct BMOperator *op, 
264                          char *slotname, int flag);
265
266 /*pointer versoins of BMO_Get_MapFloat and BMO_Insert_MapFloat.
267
268   do NOT use these for non-operator-api-allocated memory! instead
269   use BMO_Get_MapData and BMO_Insert_Mapping, which copies the data.*/
270 void BMO_Insert_MapPointer(BMesh *bm, BMOperator *op, char *slotname, 
271                         void *key, void *val);
272 void *BMO_Get_MapPointer(BMesh *bm, BMOperator *op, char *slotname,
273                        void *key);
274
275
276 /*this part of the API is used to iterate over element buffer or
277   mapping slots.
278   
279   for example, iterating over the faces in a slot is:
280
281           BMOIter oiter;
282           BMFace *f;
283
284           f = BMO_IterNew(&oiter, bm, some_operator, "slotname", BM_FACE);
285           for (; f; f=BMO_IterStep(&oiter)) {
286                 /do something with the face
287           }
288
289   another example, iterating over a mapping:
290           BMOIter oiter;
291           void *key;
292           void *val;
293
294           key = BMO_IterNew(&oiter, bm, some_operator, "slotname", 0);
295           for (; key; key=BMO_IterStep(&oiter)) {
296                 val = BMO_IterMapVal(&oiter);
297                 //do something with the key/val pair
298                 //note that val is a pointer to the val data,
299                 //whether it's a float, pointer, whatever.
300                 //
301                 // so to get a pointer, for example, use:
302                 //  *((void**)BMO_IterMapVal(&oiter));
303                 //or something like that.
304           }
305
306   */
307
308 /*contents of this structure are private,
309   don't directly access.*/
310 typedef struct BMOIter {
311         BMOpSlot *slot;
312         int cur; //for arrays
313         struct GHashIterator giter;
314         void *val;
315         int restrict;
316 } BMOIter;
317
318 /*restrictmask restricts the iteration to certain element types
319   (e.g. combination of BM_VERT, BM_EDGE, BM_FACE), if iterating
320   over an element buffer (not a mapping).*/
321 void *BMO_IterNew(BMOIter *iter, BMesh *bm, BMOperator *op, 
322                   char *slotname, int restrictmask);
323 void *BMO_IterStep(BMOIter *iter);
324
325 /*returns a pointer to the key value when iterating over mappings.
326   remember for pointer maps this will be a pointer to a pointer.*/
327 void *BMO_IterMapVal(BMOIter *iter);
328
329 #define BMO_ITER(ele, iter, bm, op, slotname, restrict) \
330         ele = BMO_IterNew(iter, bm, op, slotname, restrict); \
331         for ( ; ele; ele=BMO_IterStep(iter))
332
333 #endif /* _BMESH_OPERATOR_H */