37225ab342ed6a78b600ae7bfd2881094d4358f2
[blender.git] / source / blender / bmesh / bmesh_operators.h
1 #ifndef BM_OPERATORS_H
2 #define BM_OPERATORS_H
3
4 #include "BLI_memarena.h"
5 #include "BLI_ghash.h"
6
7 #include <stdarg.h>
8
9 #define BMOP_OPSLOT_INT                 0
10 #define BMOP_OPSLOT_FLT                 1
11 #define BMOP_OPSLOT_PNT                 2
12 #define BMOP_OPSLOT_VEC                 6
13
14 /*after BMOP_OPSLOT_VEC, everything is 
15   dynamically allocated arrays.  we
16   leave a space in the identifiers
17   for future growth.*/
18 #define BMOP_OPSLOT_PNT_BUF             7
19
20 #define BMOP_OPSLOT_MAPPING             8
21 #define BMOP_OPSLOT_TYPES               9
22
23 typedef struct BMOpSlot{
24         int slottype;
25         int len;
26         int flag;
27         int index; /*index within slot array*/
28         union {
29                 int i;
30                 float f;                                        
31                 void *p;                                        
32                 float vec[3];                           /*vector*/
33                 void *buf;                              /*buffer*/
34                 GHash *ghash;
35         } data;
36 }BMOpSlot;
37
38 /*BMOpSlot->flag*/
39 /*is a dynamically-allocated array.  set at runtime.*/
40 #define BMOS_DYNAMIC_ARRAY      1
41
42 /*operators represent logical, executable mesh modules.*/
43 #define BMOP_MAX_SLOTS                  16              /*way more than probably needed*/
44
45 typedef struct BMOperator{
46         int type;
47         int slottype;
48         int needflag;
49         struct BMOpSlot slots[BMOP_MAX_SLOTS];
50         void (*exec)(struct BMesh *bm, struct BMOperator *op);
51         MemArena *arena;
52 }BMOperator;
53
54 #define MAX_SLOTNAME    32
55
56 typedef struct slottype {
57         int type;
58         char name[MAX_SLOTNAME];
59 } slottype;
60
61 /*need to refactor code to use this*/
62 typedef struct BMOpDefine {
63         char *name;
64         slottype slottypes[BMOP_MAX_SLOTS];
65         void (*exec)(BMesh *bm, BMOperator *op);
66         int totslot;
67         int flag;
68 } BMOpDefine;
69
70 /*BMOpDefine->flag*/
71 //doesn't do anything at the moment.
72
73 /*API for operators*/
74
75 /*data types that use pointers (arrays, etc) should never
76   have it set directly.  and never use BMO_Set_Pnt to
77   pass in a list of edges or any arrays, really.*/
78 void BMO_Init_Op(struct BMOperator *op, int opcode);
79 void BMO_Exec_Op(struct BMesh *bm, struct BMOperator *op);
80 void BMO_Finish_Op(struct BMesh *bm, struct BMOperator *op);
81 BMOpSlot *BMO_GetSlot(struct BMOperator *op, int slotcode);
82 void BMO_CopySlot(struct BMOperator *source_op, struct BMOperator *dest_op, int src, int dst);
83 void BMO_Set_Float(struct BMOperator *op, int slotcode, float f);
84 void BMO_Set_Int(struct BMOperator *op, int slotcode, int i);
85 void BMO_Set_Pnt(struct BMOperator *op, int slotcode, void *p);
86 void BMO_Set_Vec(struct BMOperator *op, int slotcode, float *vec);
87 void BMO_SetFlag(struct BMesh *bm, void *element, int flag);
88 void BMO_ClearFlag(struct BMesh *bm, void *element, int flag);
89 int BMO_TestFlag(struct BMesh *bm, void *element, int flag);
90 int BMO_CountFlag(struct BMesh *bm, int flag, int type);
91 void BMO_Flag_To_Slot(struct BMesh *bm, struct BMOperator *op, int slotcode, int flag, int type);
92 void BMO_Flag_Buffer(struct BMesh *bm, struct BMOperator *op, int slotcode, int flag);
93 void BMO_Unflag_Buffer(struct BMesh *bm, struct BMOperator *op, int slotcode, int flag);
94 void BMO_HeaderFlag_To_Slot(struct BMesh *bm, struct BMOperator *op, int slotcode, int flag, int type);
95 int BMO_CountSlotBuf(struct BMesh *bm, struct BMOperator *op, int slotcode);
96
97 /*copies data, doesn't store a reference to it.*/
98 void BMO_Insert_Mapping(BMesh *bm, BMOperator *op, int slotcode, 
99                         void *element, void *data, int len);
100 void BMO_Insert_MapFloat(BMesh *bm, BMOperator *op, int slotcode, 
101                         void *element, float val);
102
103 //returns 1 if the specified element is in the map.
104 int BMO_InMap(BMesh *bm, BMOperator *op, int slotcode, void *element);
105 void *BMO_Get_MapData(BMesh *bm, BMOperator *op, int slotcode,
106                       void *element);
107 float BMO_Get_MapFloat(BMesh *bm, BMOperator *op, int slotcode,
108                        void *element);
109 void BMO_Mapping_To_Flag(struct BMesh *bm, struct BMOperator *op, 
110                          int slotcode, int flag);
111
112 /*do NOT use these for non-operator-api-allocated memory! instead
113   use BMO_Get_MapData, which copies the data.*/
114 void BMO_Insert_MapPointer(BMesh *bm, BMOperator *op, int slotcode, 
115                         void *element, void *val);
116 void *BMO_Get_MapPointer(BMesh *bm, BMOperator *op, int slotcode,
117                        void *element);
118
119 struct GHashIterator;
120 typedef struct BMOIter {
121         BMOpSlot *slot;
122         int cur; //for arrays
123         struct GHashIterator giter;
124         void *val;
125 } BMOIter;
126
127 void *BMO_IterNew(BMOIter *iter, BMesh *bm, BMOperator *op, 
128                   int slotcode);
129 void *BMO_IterStep(BMOIter *iter);
130
131 /*returns a pointer to the key value when iterating over mappings.
132   remember for pointer maps this will be a pointer to a pointer.*/
133 void *BMO_IterMapVal(BMOIter *iter);
134
135 /*formatted operator initialization/execution*/
136 int BMO_CallOpf(BMesh *bm, char *fmt, ...);
137 int BMO_InitOpf(BMesh *bm, BMOperator *op, char *fmt, ...);
138 int BMO_VInitOpf(BMesh *bm, BMOperator *op, char *fmt, va_list vlist);
139
140 /*----------- bmop error system ----------*/
141
142 /*pushes an error onto the bmesh error stack.
143   if msg is null, then the default message for the errorcode is used.*/
144 void BMO_RaiseError(BMesh *bm, BMOperator *owner, int errcode, char *msg);
145
146 /*gets the topmost error from the stack.
147   returns error code or 0 if no error.*/
148 int BMO_GetError(BMesh *bm, char **msg, BMOperator **op);
149 int BMO_HasError(BMesh *bm);
150
151 /*same as geterror, only pops the error off the stack as well*/
152 int BMO_PopError(BMesh *bm, char **msg, BMOperator **op);
153 void BMO_ClearStack(BMesh *bm);
154
155 #if 0
156 //this is meant for handling errors, like self-intersection test failures.
157 //it's dangerous to handle errors in general though, so disabled for now.
158
159 /*catches an error raised by the op pointed to by catchop.
160   errorcode is either the errorcode, or BMERR_ALL for any 
161   error.*/
162 int BMO_CatchOpError(BMesh *bm, BMOperator *catchop, int errorcode, char **msg);
163 #endif
164
165 /*------ error code defines -------*/
166
167 /*error messages*/
168 #define BMERR_SELF_INTERSECTING                 1
169 #define BMERR_DISSOLVEDISK_FAILED               2
170 #define BMERR_CONNECTVERT_FAILED                3
171 #define BMERR_WALKER_FAILED                     4
172 #define BMERR_DISSOLVEFACES_FAILED              5
173 #define BMERR_DISSOLVEVERTS_FAILED              6
174
175 static char *bmop_error_messages[] = {
176        0,
177        "Self intersection error",
178        "Could not dissolve vert",
179        "Could not connect verts",
180        "Could not traverse mesh",
181        "Could not dissolve faces",
182        "Could not dissolve vertices",
183 };
184
185 /*------------begin operator defines (see bmesh_opdefines.c too)------------*/
186 /*split op*/
187 #define BMOP_SPLIT                              0
188
189 enum {
190         BMOP_SPLIT_MULTIN,
191         BMOP_SPLIT_MULTOUT,
192         BMOP_SPLIT_BOUNDS_EDGEMAP, //bounding edges of split faces
193         BMOP_SPLIT_TOTSLOT,
194 };
195
196 /*dupe op*/
197 #define BMOP_DUPE       1
198
199 enum {
200         BMOP_DUPE_MULTIN,
201         BMOP_DUPE_ORIG,
202         BMOP_DUPE_NEW,
203         /*we need a map for verts duplicated not connected
204           to any faces, too.*/  
205         BMOP_DUPE_BOUNDS_EDGEMAP,
206         BMOP_DUPE_TOTSLOT
207 };
208
209 /*delete op*/
210 #define BMOP_DEL        2
211
212 enum {
213         BMOP_DEL_MULTIN,
214         BMOP_DEL_CONTEXT,
215         BMOP_DEL_TOTSLOT,
216 };
217
218 #define DEL_VERTS               1
219 #define DEL_EDGES               2
220 #define DEL_ONLYFACES   3
221 #define DEL_EDGESFACES  4
222 #define DEL_FACES               5
223 #define DEL_ALL                 6
224 #define DEL_ONLYTAGGED          7
225
226 /*BMOP_DEL_CONTEXT*/
227 enum {
228         BMOP_DEL_VERTS = 1,
229         BMOP_DEL_EDGESFACES,
230         BMOP_DEL_ONLYFACES,
231         BMOP_DEL_FACES,
232         BMOP_DEL_ALL,
233 };
234
235 /*editmesh->bmesh op*/
236 #define BMOP_FROM_EDITMESH              3
237 enum {
238         BMOP_FROM_EDITMESH_EM,
239         BMOP_FROM_EDITMESH_TOTSLOT,
240 };
241
242 #define BMOP_TO_EDITMESH                4
243 /*bmesh->editmesh op*/
244 enum {
245         BMOP_TO_EDITMESH_EMOUT,
246         BMOP_TO_EDITMESH_TOTSLOT,
247 };
248
249 /*edge subdivide op*/
250 #define BMOP_ESUBDIVIDE                 5
251 enum {
252         BMOP_ESUBDIVIDE_EDGES,
253         BMOP_ESUBDIVIDE_NUMCUTS,
254         BMOP_ESUBDIVIDE_FLAG, //beauty flag in esubdivide
255         BMOP_ESUBDIVIDE_RADIUS,
256
257         BMOP_ESUBDIVIDE_CUSTOMFILL_FACEMAP,
258         BMOP_ESUBDIVIDE_PERCENT_EDGEMAP,
259
260         /*inner verts/new faces of completely filled faces, e.g.
261           fully selected face.*/
262         BMOP_ESUBDIVIDE_INNER_MULTOUT,
263
264         /*new edges and vertices from splitting original edges,
265           doesn't include edges creating by connecting verts.*/
266         BMOP_ESUBDIVIDE_SPLIT_MULTOUT,  
267         BMOP_ESUBDIVIDE_TOTSLOT,
268 };
269 /*
270 SUBDIV_SELECT_INNER
271 SUBDIV_SELECT_ORIG
272 SUBDIV_SELECT_INNER_SEL
273 SUBDIV_SELECT_LOOPCUT
274 DOUBLEOPFILL
275 */
276
277 /*triangulate*/
278 #define BMOP_TRIANGULATE                6
279
280 enum {
281         BMOP_TRIANG_FACEIN,
282         BMOP_TRIANG_NEW_EDGES,
283         BMOP_TRIANG_NEW_FACES,
284         BMOP_TRIANG_TOTSLOT,
285 };
286
287 /*dissolve faces*/
288 #define BMOP_DISSOLVE_FACES             7
289 enum {
290         BMOP_DISFACES_FACEIN,
291         //list of faces that comprise regions of split faces
292         BMOP_DISFACES_REGIONOUT,
293         BMOP_DISFACES_TOTSLOT,
294 };
295
296 /*dissolve verts*/
297 #define BMOP_DISSOLVE_VERTS             8
298
299 enum {
300         BMOP_DISVERTS_VERTIN,
301         BMOP_DISVERTS_TOTSLOT,
302 };
303
304 #define BMOP_MAKE_FGONS                 9
305 #define BMOP_MAKE_FGONS_TOTSLOT 0
306
307 #define BMOP_EXTRUDE_EDGECONTEXT        10
308 enum {
309         BMOP_EXFACE_EDGEFACEIN,
310         BMOP_EXFACE_EXCLUDEMAP, //exclude edges from skirt connecting
311         BMOP_EXFACE_MULTOUT, //new geometry
312         BMOP_EXFACE_TOTSLOT,
313 };
314
315 #define BMOP_CONNECT_VERTS              11
316 enum {
317         BM_CONVERTS_VERTIN,
318         BM_CONVERTS_EDGEOUT,
319         BM_CONVERTS_TOTSLOT
320 };
321
322 /*keep this updated!*/
323 #define BMOP_TOTAL_OPS                  12
324 /*-------------------------------end operator defines-------------------------------*/
325
326 extern BMOpDefine *opdefines[];
327 extern int bmesh_total_ops;
328
329 /*------specific operator helper functions-------*/
330
331 /*executes the duplicate operation, feeding elements of 
332   type flag etypeflag and header flag flag to it.  note,
333   to get more useful information (such as the mapping from
334   original to new elements) you should run the dupe op manually.*/
335 struct Object;
336 struct EditMesh;
337
338 void BMOP_DupeFromFlag(struct BMesh *bm, int etypeflag, int flag);
339 void BM_esubdivideflag(struct Object *obedit, struct BMesh *bm, int selflag, float rad, 
340                int flag, int numcuts, int seltype);
341 void BM_extrudefaceflag(BMesh *bm, int flag);
342
343 /*these next two return 1 if they did anything, or zero otherwise.
344   they're kindof a hackish way to integrate with fkey, until
345   such time as fkey is completely bmeshafied.*/
346 int BM_DissolveFaces(struct EditMesh *em, int flag);
347 /*this doesn't display errors to the user, btw*/
348 int BM_ConnectVerts(struct EditMesh *em, int flag);
349
350 #endif