bmesh minor refactor
[blender.git] / source / blender / bmesh / bmesh.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): Geoffrey Bantle, Levi Schooley.
19  *
20  * ***** END GPL LICENSE BLOCK *****
21  */
22
23 #ifndef __BMESH_H__
24 #define __BMESH_H__
25
26 /** \file blender/bmesh/bmesh.h
27  *  \ingroup bmesh
28  */
29
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33
34 #include "DNA_listBase.h"
35 #include "DNA_customdata_types.h"
36
37 #include "BLI_utildefines.h"
38
39 #include "bmesh_class.h"
40
41 /*
42  * short introduction:
43  *
44  * the bmesh structure is a boundary representation, supporting non-manifold
45  * locally modifiable topology. the API is designed to allow clean, maintainable
46  * code, that never (or almost never) directly inspects the underlying structure.
47  *
48  * The API includes iterators, including many useful topological iterators;
49  * walkers, which walk over a mesh, without the risk of hitting the recursion
50  * limit; operators, which are logical, reusable mesh modules; topological
51  * modification functions (like split face, join faces, etc), which are used for
52  * topological manipulations; and some (not yet finished) geometric utility
53  * functions.
54  *
55  * some definitions:
56  *
57  * tool flags: private flags for tools.  each operator has it's own private
58  *             tool flag "layer", which it can use to flag elements.
59  *             tool flags are also used by various other parts of the api.
60  * header flags: stores persistent flags, such as selection state, hide state,
61  *               etc.  be careful of touching these.
62  */
63
64 /*forward declarations*/
65 struct BMesh;
66 struct BMVert;
67 struct BMEdge;
68 struct BMFace;
69 struct BMLoop;
70 struct BMOperator;
71 struct Mesh;
72 struct EditMesh;
73
74 /*
75  * BMHeader
76  *
77  * All mesh elements begin with a BMHeader. This structure
78  * hold several types of data
79  *
80  * 1: The type of the element (vert, edge, loop or face)
81  * 2: Persistant "header" flags/markings (sharp, seam, select, hidden, ect)
82       note that this is different from the "tool" flags.
83  * 3: Unique ID in the bmesh.
84  * 4: some elements for internal record keeping.
85  *
86 */
87
88 /* BMHeader->htype (char) */
89 #define BM_VERT         1
90 #define BM_EDGE         2
91 #define BM_LOOP         4
92 #define BM_FACE         8
93 #define BM_ALL          (BM_VERT | BM_EDGE | BM_LOOP | BM_FACE)
94
95 /* BMHeader->hflag (char, all bits used!) */
96 #define BM_ELEM_SELECT  (1<<0)
97 #define BM_ELEM_HIDDEN  (1<<1)
98 #define BM_ELEM_SEAM    (1<<2)
99 #define BM_ELEM_SHARP   (1<<3)
100 #define BM_ELEM_SMOOTH  (1<<4)
101 #define BM_ELEM_TAG     (1<<5) /* internal flag, used for ensuring correct normals
102                                 * during multires interpolation, and any other time
103                                 * when temp tagging is handy.
104                                 * always assume dirty & clear before use. */
105
106 /* we have 2 spare flags which is awesome but since we're limited to 8
107  * only add new flags with care! - campbell */
108 /* #define BM_TMP_SPARE  (1<<6) */
109 /* #define BM_NONORMCALC (1<<7) */ /* UNUSED */
110
111 /* stub */
112 void bmesh_error(void);
113
114 /* Mesh Level Ops */
115 extern int bm_mesh_allocsize_default[4];
116
117 /* ob is needed by multires */
118 BMesh *BM_mesh_create(struct Object *ob, const int allocsize[4]);
119 BMesh *BM_mesh_copy(BMesh *bmold);
120 void   BM_mesh_free(BMesh *bm);
121
122 /* frees mesh, but not actual BMesh struct */
123 void BM_mesh_data_free(BMesh *bm);
124 void BM_mesh_normals_update(BMesh *bm);
125
126 /* Construction */
127 BMVert *BM_vert_create(BMesh *bm, const float co[3], const BMVert *example);
128 BMEdge *BM_edge_create(BMesh *bm, BMVert *v1, BMVert *v2, const BMEdge *example, int nodouble);
129 BMFace *BM_face_create(BMesh *bm, BMVert **verts, BMEdge **edges, const int len, int nodouble);
130
131 BMFace *BM_face_create_quad_tri_v(BMesh *bm,
132                                   BMVert **verts, int len,
133                                   const BMFace *example, const int nodouble);
134
135 /* easier to use version of BM_face_create_quad_tri_v.
136  * creates edges if necassary. */
137 BMFace *BM_face_create_quad_tri(BMesh *bm, BMVert *v1, BMVert *v2, BMVert *v3, BMVert *v4,
138                                 const BMFace *example, const int nodouble);
139
140 /* makes an ngon from an unordered list of edges.  v1 and v2 must be the verts
141  * defining edges[0], and define the winding of the new face. */
142 BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, int len, int nodouble);
143
144 /* stuff for dealing with header flags */
145 BM_INLINE char BM_elem_flag_test(const void *element, const char hflag);
146
147 /* stuff for dealing with header flags */
148 BM_INLINE void BM_elem_flag_set(void *element, const char hflag);
149
150 /* stuff for dealing with header flags */
151 BM_INLINE void BM_elem_flag_clear(void *element, const char hflag);
152
153 /* stuff for dealing BM_elem_flag_toggle header flags */
154 BM_INLINE void BM_elem_flag_toggle(void *element, const char hflag);
155 BM_INLINE void BM_elem_flag_merge(void *element_a, void *element_b);
156
157 /* notes on BM_elem_index_set(...) usage,
158  * Set index is sometimes abused as temp storage, other times we cant be
159  * sure if the index values are valid because certain operations have modified
160  * the mesh structure.
161  *
162  * To set the elements to valid indicies 'BM_mesh_elem_index_ensure' should be used
163  * rather then adding inline loops, however there are cases where we still
164  * set the index directly
165  *
166  * In an attempt to manage this, here are 3 tags Im adding to uses of
167  * 'BM_elem_index_set'
168  *
169  * - 'set_inline'  -- since the data is already being looped over set to a
170  *                    valid value inline.
171  *
172  * - 'set_dirty!'  -- intentionally sets the index to an invalid value,
173  *                    flagging 'bm->elem_index_dirty' so we dont use it.
174  *
175  * - 'set_ok'      -- this is valid use since the part of the code is low level.
176  *
177  * - 'set_ok_invalid'  -- set to -1 on purpose since this should not be
178  *                    used without a full array re-index, do this on
179  *                    adding new vert/edge/faces since they may be added at
180  *                    the end of the array.
181  *
182  * - 'set_loop'    -- currently loop index values are not used used much so
183  *                    assume each case they are dirty.
184  * - campbell */
185
186 BM_INLINE void BM_elem_index_set(void *element, const int index);
187 BM_INLINE int  BM_elem_index_get(const void *element);
188
189 /* todo */
190 BMFace *BM_face_copy(BMesh *bm, BMFace *f, int copyedges, int copyverts);
191
192 /* copies loop data from adjacent faces */
193 void BM_face_copy_shared(BMesh *bm, BMFace *f);
194
195 /* copies attributes, e.g. customdata, header flags, etc, from one element
196  * to another of the same type.*/
197 void BM_elem_copy_attrs(BMesh *source_mesh, BMesh *target_mesh, const void *source, void *target);
198
199 /* Modification */
200 /* join two adjacent faces together along an edge.  note that
201  * the faces must only be joined by on edge.  e is the edge you
202  * wish to dissolve.*/
203 BMFace *BM_faces_join_pair(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e);
204
205 /* generic, flexible join faces function; note that most everything uses
206  * this, including BM_faces_join_pair */
207 BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface);
208
209 /* split a face along two vertices.  returns the newly made face, and sets
210  * the nl member to a loop in the newly created edge.*/
211 BMFace *BM_face_split(BMesh *bm, BMFace *f,
212                       BMVert *v1, BMVert *v2,
213                       struct BMLoop **nl, BMEdge *example);
214
215 /* these 2 functions are very similar */
216 BMEdge* BM_vert_collapse_faces(BMesh *bm, BMEdge *ke, BMVert *kv, float fac, const int join_faces);
217 BMEdge* BM_vert_collapse_edges(BMesh *bm, BMEdge *ke, BMVert *kv);
218
219
220 /* splits an edge.  ne is set to the new edge created. */
221 BMVert *BM_edge_split(BMesh *bm, BMVert *v, BMEdge *e, BMEdge **ne, float percent);
222
223 /* split an edge multiple times evenly */
224 BMVert  *BM_edge_split_n(BMesh *bm, BMEdge *e, int numcuts);
225
226 /* connect two verts together, through a face they share.  this function may
227  * be removed in the future. */
228 BMEdge *BM_verts_connect(BMesh *bm, BMVert *v1, BMVert *v2, BMFace **nf);
229
230 /* rotates an edge topologically, either clockwise (if ccw=0) or counterclockwise
231  * (if ccw is 1). */
232 BMEdge *BM_edge_rotate(BMesh *bm, BMEdge *e, int ccw);
233
234 /* Rip a single face from a vertex fan */
235 BMVert *BM_vert_rip(BMesh *bm, BMFace *sf, BMVert *sv);
236
237 /*updates a face normal*/
238 void BM_face_normal_update(BMesh *bm, BMFace *f);
239 void BM_face_normal_update_vcos(BMesh *bm, BMFace *f, float no[3], float (*vertexCos)[3]);
240
241 /*updates face and vertex normals incident on an edge*/
242 void BM_edge_normals_update(BMesh *bm, BMEdge *e);
243
244 /*update a vert normal (but not the faces incident on it)*/
245 void BM_vert_normal_update(BMesh *bm, BMVert *v);
246 void BM_vert_normal_update_all(BMesh *bm, BMVert *v);
247
248 void BM_face_normal_flip(BMesh *bm, BMFace *f);
249
250 /*dissolves all faces around a vert, and removes it.*/
251 int BM_disk_dissolve(BMesh *bm, BMVert *v);
252
253 /* dissolves vert, in more situations then BM_disk_dissolve
254  * (e.g. if the vert is part of a wire edge, etc).*/
255 int BM_vert_dissolve(BMesh *bm, BMVert *v);
256
257 /* Projects co onto face f, and returns true if it is inside
258  * the face bounds.  Note that this uses a best-axis projection
259  * test, instead of projecting co directly into f's orientation
260  * space, so there might be accuracy issues.*/
261 int BM_face_point_inside_test(BMesh *bm, BMFace *f, const float co[3]);
262
263 /* Interpolation */
264
265 /* projects target onto source for customdata interpolation.  note: only
266  * does loop customdata.  multires is handled.  */
267 void BM_face_interp_from_face(BMesh *bm, BMFace *target, BMFace *source);
268
269 /* projects a single loop, target, onto source for customdata interpolation. multires is handled.
270  * if do_vertex is true, target's vert data will also get interpolated.*/
271 void BM_loop_interp_from_face(BMesh *bm, BMLoop *target, BMFace *source,
272                               int do_vertex, int do_multires);
273
274 /* smoothes boundaries between multires grids, including some borders in adjacent faces */
275 void BM_face_multires_bounds_smooth(BMesh *bm, BMFace *f);
276
277 /* project the multires grid in target onto source's set of multires grids */
278 void BM_loop_interp_multires(BMesh *bm, BMLoop *target, BMFace *source);
279 void BM_vert_interp_from_face(BMesh *bm, BMVert *v, BMFace *source);
280
281 void  BM_data_interp_from_verts(BMesh *bm, BMVert *v1, BMVert *v2, BMVert *v, float fac);
282 void  BM_data_interp_face_vert_edge(BMesh *bm, BMVert *v1, BMVert *v2, BMVert *v, struct BMEdge *e1, float fac);
283 void  BM_data_layer_add(BMesh *em, CustomData *data, int type);
284 void  BM_data_layer_add_named(BMesh *bm, CustomData *data, int type, const char *name);
285 void  BM_data_layer_free(BMesh *em, CustomData *data, int type);
286 void  BM_data_layer_free_n(BMesh *bm, CustomData *data, int type, int n);
287 float BM_elem_float_data_get(struct CustomData *cd, void *element, int type);
288 void  BM_elem_float_data_set(struct CustomData *cd, void *element, int type, const float val);
289
290 /* get the area of the face */
291 float BM_face_area_calc(BMesh *bm, BMFace *f);
292 /* computes the centroid of a face, using the center of the bounding box */
293 void BM_face_center_bounds_calc(BMesh *bm, BMFace *f, float center[3]);
294 /* computes the centroid of a face, using the mean average */
295 void BM_face_center_mean_calc(BMesh *bm, BMFace *f, float center[3]);
296
297 void BM_mesh_select_mode_flush(BMesh *bm);
298
299 /* mode independant flushing up/down */
300 void BM_mesh_deselect_flush(BMesh *bm);
301 void BM_mesh_select_flush(BMesh *bm);
302
303 /* flag conversion funcs */
304 char BM_face_flag_from_mflag(const char  mflag);
305 char BM_edge_flag_from_mflag(const short mflag);
306 char BM_vert_flag_from_mflag(const char  mflag);
307 /* reverse */
308 char  BM_face_flag_to_mflag(BMFace *f);
309 short BM_edge_flag_to_mflag(BMEdge *e);
310 char  BM_vert_flag_to_mflag(BMVert *v);
311
312
313 /* convert MLoop*** in a bmface to mtface and mcol in
314  * an MFace*/
315 void BM_loops_to_corners(BMesh *bm, struct Mesh *me, int findex,
316                          BMFace *f, int numTex, int numCol);
317
318 void BM_loop_kill(BMesh *bm, BMLoop *l);
319 void BM_face_kill(BMesh *bm, BMFace *f);
320 void BM_edge_kill(BMesh *bm, BMEdge *e);
321 void BM_vert_kill(BMesh *bm, BMVert *v);
322
323 /* kills all edges associated with f, along with any other faces containing
324  * those edges*/
325 void BM_face_edges_kill(BMesh *bm, BMFace *f);
326
327 /* kills all verts associated with f, along with any other faces containing
328  * those vertices*/
329 void BM_face_verts_kill(BMesh *bm, BMFace *f);
330
331 /*clear all data in bm*/
332 void BM_mesh_clear(BMesh *bm);
333
334 void BM_mesh_elem_index_ensure(BMesh *bm, const char hflag);
335
336 void BM_mesh_elem_index_validate(BMesh *bm, const char *location, const char *func,
337                                  const char *msg_a, const char *msg_b);
338
339 BMVert *BM_vert_at_index(BMesh *bm, const int index);
340 BMEdge *BM_edge_at_index(BMesh *bm, const int index);
341 BMFace *BM_face_at_index(BMesh *bm, const int index);
342
343 /*start/stop edit*/
344 void bmesh_begin_edit(BMesh *bm, int flag);
345 void bmesh_end_edit(BMesh *bm, int flag);
346
347
348 #define BM_FACE_FIRST_LOOP(p) (((BMLoopList *)((p)->loops.first))->first)
349
350 /* size to use for static arrays when dealing with NGons,
351  * alloc after this limit is reached.
352  * this value is rather arbitrary */
353 #define BM_NGON_STACK_SIZE 32
354
355 /* avoid inf loop, this value is arbtrary
356  * but should not error on valid cases */
357 #define BM_LOOP_RADIAL_MAX 10000
358 #define BM_NGON_MAX 100000
359
360 /* include the rest of the API */
361 #include "bmesh_marking.h"
362 #include "bmesh_operator_api.h"
363 #include "bmesh_operators.h"
364 #include "bmesh_error.h"
365 #include "bmesh_queries.h"
366 #include "bmesh_iterators.h"
367 #include "bmesh_walkers.h"
368 #include "intern/bmesh_inline.c"
369
370 #ifdef __cplusplus
371 }
372 #endif
373
374 #endif /* __BMESH_H__ */