dissolve faces: errors-out on holes, preserves winding, and doesn't delete original...
[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
90 /*flags 15 and 16 (1<<14 and 1<<15) are reserved for bmesh api use*/
91 int BMO_TestFlag(struct BMesh *bm, void *element, int flag);
92 int BMO_CountFlag(struct BMesh *bm, int flag, int type);
93 void BMO_Flag_To_Slot(struct BMesh *bm, struct BMOperator *op, int slotcode, int flag, int type);
94 void BMO_Flag_Buffer(struct BMesh *bm, struct BMOperator *op, int slotcode, int flag);
95 void BMO_Unflag_Buffer(struct BMesh *bm, struct BMOperator *op, int slotcode, int flag);
96 void BMO_HeaderFlag_To_Slot(struct BMesh *bm, struct BMOperator *op, int slotcode, int flag, int type);
97 int BMO_CountSlotBuf(struct BMesh *bm, struct BMOperator *op, int slotcode);
98
99 /*copies data, doesn't store a reference to it.*/
100 void BMO_Insert_Mapping(BMesh *bm, BMOperator *op, int slotcode, 
101                         void *element, void *data, int len);
102 void BMO_Insert_MapFloat(BMesh *bm, BMOperator *op, int slotcode, 
103                         void *element, float val);
104
105 //returns 1 if the specified element is in the map.
106 int BMO_InMap(BMesh *bm, BMOperator *op, int slotcode, void *element);
107 void *BMO_Get_MapData(BMesh *bm, BMOperator *op, int slotcode,
108                       void *element);
109 float BMO_Get_MapFloat(BMesh *bm, BMOperator *op, int slotcode,
110                        void *element);
111 void BMO_Mapping_To_Flag(struct BMesh *bm, struct BMOperator *op, 
112                          int slotcode, int flag);
113
114 /*do NOT use these for non-operator-api-allocated memory! instead
115   use BMO_Get_MapData, which copies the data.*/
116 void BMO_Insert_MapPointer(BMesh *bm, BMOperator *op, int slotcode, 
117                         void *element, void *val);
118 void *BMO_Get_MapPointer(BMesh *bm, BMOperator *op, int slotcode,
119                        void *element);
120
121 struct GHashIterator;
122 typedef struct BMOIter {
123         BMOpSlot *slot;
124         int cur; //for arrays
125         struct GHashIterator giter;
126         void *val;
127 } BMOIter;
128
129 void *BMO_IterNew(BMOIter *iter, BMesh *bm, BMOperator *op, 
130                   int slotcode);
131 void *BMO_IterStep(BMOIter *iter);
132
133 /*returns a pointer to the key value when iterating over mappings.
134   remember for pointer maps this will be a pointer to a pointer.*/
135 void *BMO_IterMapVal(BMOIter *iter);
136
137 /*formatted operator initialization/execution*/
138 int BMO_CallOpf(BMesh *bm, char *fmt, ...);
139 int BMO_InitOpf(BMesh *bm, BMOperator *op, char *fmt, ...);
140 int BMO_VInitOpf(BMesh *bm, BMOperator *op, char *fmt, va_list vlist);
141
142 /*----------- bmop error system ----------*/
143
144 /*pushes an error onto the bmesh error stack.
145   if msg is null, then the default message for the errorcode is used.*/
146 void BMO_RaiseError(BMesh *bm, BMOperator *owner, int errcode, char *msg);
147
148 /*gets the topmost error from the stack.
149   returns error code or 0 if no error.*/
150 int BMO_GetError(BMesh *bm, char **msg, BMOperator **op);
151 int BMO_HasError(BMesh *bm);
152
153 /*same as geterror, only pops the error off the stack as well*/
154 int BMO_PopError(BMesh *bm, char **msg, BMOperator **op);
155 void BMO_ClearStack(BMesh *bm);
156
157 #if 0
158 //this is meant for handling errors, like self-intersection test failures.
159 //it's dangerous to handle errors in general though, so disabled for now.
160
161 /*catches an error raised by the op pointed to by catchop.
162   errorcode is either the errorcode, or BMERR_ALL for any 
163   error.*/
164 int BMO_CatchOpError(BMesh *bm, BMOperator *catchop, int errorcode, char **msg);
165 #endif
166
167 /*------ error code defines -------*/
168
169 /*error messages*/
170 #define BMERR_SELF_INTERSECTING                 1
171 #define BMERR_DISSOLVEDISK_FAILED               2
172 #define BMERR_CONNECTVERT_FAILED                3
173 #define BMERR_WALKER_FAILED                     4
174 #define BMERR_DISSOLVEFACES_FAILED              5
175 #define BMERR_DISSOLVEVERTS_FAILED              6
176
177 static char *bmop_error_messages[] = {
178        0,
179        "Self intersection error",
180        "Could not dissolve vert",
181        "Could not connect verts",
182        "Could not traverse mesh",
183        "Could not dissolve faces",
184        "Could not dissolve vertices",
185 };
186
187 /*------------begin operator defines (see bmesh_opdefines.c too)------------*/
188 /*split op*/
189 #define BMOP_SPLIT                              0
190
191 enum {
192         BMOP_SPLIT_MULTIN,
193         BMOP_SPLIT_MULTOUT,
194         BMOP_SPLIT_BOUNDS_EDGEMAP, //bounding edges of split faces
195         BMOP_SPLIT_TOTSLOT,
196 };
197
198 /*dupe op*/
199 #define BMOP_DUPE       1
200
201 enum {
202         BMOP_DUPE_MULTIN,
203         BMOP_DUPE_ORIG,
204         BMOP_DUPE_NEW,
205         /*we need a map for verts duplicated not connected
206           to any faces, too.*/  
207         BMOP_DUPE_BOUNDS_EDGEMAP,
208         BMOP_DUPE_TOTSLOT
209 };
210
211 /*delete op*/
212 #define BMOP_DEL        2
213
214 enum {
215         BMOP_DEL_MULTIN,
216         BMOP_DEL_CONTEXT,
217         BMOP_DEL_TOTSLOT,
218 };
219
220 #define DEL_VERTS               1
221 #define DEL_EDGES               2
222 #define DEL_ONLYFACES   3
223 #define DEL_EDGESFACES  4
224 #define DEL_FACES               5
225 #define DEL_ALL                 6
226 #define DEL_ONLYTAGGED          7
227
228 /*BMOP_DEL_CONTEXT*/
229 enum {
230         BMOP_DEL_VERTS = 1,
231         BMOP_DEL_EDGESFACES,
232         BMOP_DEL_ONLYFACES,
233         BMOP_DEL_FACES,
234         BMOP_DEL_ALL,
235 };
236
237 /*editmesh->bmesh op*/
238 #define BMOP_FROM_EDITMESH              3
239 enum {
240         BMOP_FROM_EDITMESH_EM,
241         BMOP_FROM_EDITMESH_TOTSLOT,
242 };
243
244 #define BMOP_TO_EDITMESH                4
245 /*bmesh->editmesh op*/
246 enum {
247         BMOP_TO_EDITMESH_EMOUT,
248         BMOP_TO_EDITMESH_TOTSLOT,
249 };
250
251 /*edge subdivide op*/
252 #define BMOP_ESUBDIVIDE                 5
253 enum {
254         BMOP_ESUBDIVIDE_EDGES,
255         BMOP_ESUBDIVIDE_NUMCUTS,
256         BMOP_ESUBDIVIDE_FLAG, //beauty flag in esubdivide
257         BMOP_ESUBDIVIDE_RADIUS,
258
259         BMOP_ESUBDIVIDE_CUSTOMFILL_FACEMAP,
260         BMOP_ESUBDIVIDE_PERCENT_EDGEMAP,
261
262         /*inner verts/new faces of completely filled faces, e.g.
263           fully selected face.*/
264         BMOP_ESUBDIVIDE_INNER_MULTOUT,
265
266         /*new edges and vertices from splitting original edges,
267           doesn't include edges creating by connecting verts.*/
268         BMOP_ESUBDIVIDE_SPLIT_MULTOUT,  
269         BMOP_ESUBDIVIDE_TOTSLOT,
270 };
271 /*
272 SUBDIV_SELECT_INNER
273 SUBDIV_SELECT_ORIG
274 SUBDIV_SELECT_INNER_SEL
275 SUBDIV_SELECT_LOOPCUT
276 DOUBLEOPFILL
277 */
278
279 /*triangulate*/
280 #define BMOP_TRIANGULATE                6
281
282 enum {
283         BMOP_TRIANG_FACEIN,
284         BMOP_TRIANG_NEW_EDGES,
285         BMOP_TRIANG_NEW_FACES,
286         BMOP_TRIANG_TOTSLOT,
287 };
288
289 /*dissolve faces*/
290 #define BMOP_DISSOLVE_FACES             7
291 enum {
292         BMOP_DISFACES_FACEIN,
293         //list of faces that comprise regions of split faces
294         BMOP_DISFACES_REGIONOUT,
295         BMOP_DISFACES_TOTSLOT,
296 };
297
298 /*dissolve verts*/
299 #define BMOP_DISSOLVE_VERTS             8
300
301 enum {
302         BMOP_DISVERTS_VERTIN,
303         BMOP_DISVERTS_TOTSLOT,
304 };
305
306 #define BMOP_MAKE_FGONS                 9
307 #define BMOP_MAKE_FGONS_TOTSLOT 0
308
309 #define BMOP_EXTRUDE_EDGECONTEXT        10
310 enum {
311         BMOP_EXFACE_EDGEFACEIN,
312         BMOP_EXFACE_EXCLUDEMAP, //exclude edges from skirt connecting
313         BMOP_EXFACE_MULTOUT, //new geometry
314         BMOP_EXFACE_TOTSLOT,
315 };
316
317 #define BMOP_CONNECT_VERTS              11
318 enum {
319         BM_CONVERTS_VERTIN,
320         BM_CONVERTS_EDGEOUT,
321         BM_CONVERTS_TOTSLOT
322 };
323
324 /*keep this updated!*/
325 #define BMOP_TOTAL_OPS                  12
326 /*-------------------------------end operator defines-------------------------------*/
327
328 extern BMOpDefine *opdefines[];
329 extern int bmesh_total_ops;
330
331 /*------specific operator helper functions-------*/
332
333 /*executes the duplicate operation, feeding elements of 
334   type flag etypeflag and header flag flag to it.  note,
335   to get more useful information (such as the mapping from
336   original to new elements) you should run the dupe op manually.*/
337 struct Object;
338 struct EditMesh;
339
340 void BMOP_DupeFromFlag(struct BMesh *bm, int etypeflag, int flag);
341 void BM_esubdivideflag(struct Object *obedit, struct BMesh *bm, int selflag, float rad, 
342                int flag, int numcuts, int seltype);
343 void BM_extrudefaceflag(BMesh *bm, int flag);
344
345 /*this next one return 1 if they did anything, or zero otherwise.
346   they're kindof a hackish way to integrate with fkey, until
347   such time as fkey is completely bmeshafied.*/
348 /*this doesn't display errors to the user, btw*/
349 int BM_ConnectVerts(struct EditMesh *em, int flag);
350
351 #endif