2 * ***** BEGIN GPL LICENSE BLOCK *****
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.
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.
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.
18 * Contributor(s): Geoffrey Bantle, Levi Schooley.
20 * ***** END GPL LICENSE BLOCK *****
26 /** \file blender/bmesh/bmesh.h
34 #include "DNA_listBase.h"
35 #include "DNA_customdata_types.h"
37 #include "BLI_utildefines.h"
39 #include "bmesh_class.h"
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.
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
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.
64 /*forward declarations*/
77 * All mesh elements begin with a BMHeader. This structure
78 * hold several types of data
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.
88 /* BMHeader->htype (char) */
93 #define BM_ALL (BM_VERT | BM_EDGE | BM_LOOP | BM_FACE)
95 /* BMHeader->hflag (char) */
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_SMOOTH (1 << 3) /* used for faces and edges, note from the user POV,
100 * this is a sharp edge when disabled */
102 #define BM_ELEM_TAG (1 << 4) /* internal flag, used for ensuring correct normals
103 * during multires interpolation, and any other time
104 * when temp tagging is handy.
105 * always assume dirty & clear before use. */
107 /* we have 3 spare flags which is awesome but since we're limited to 8
108 * only add new flags with care! - campbell */
109 /* #define BM_ELEM_SPARE (1<<5) */
110 /* #define BM_ELEM_SPARE (1<<6) */
111 /* #define BM_ELEM_NONORMCALC (1<<7) */ /* UNUSED */
114 void bmesh_error(void);
117 extern int bm_mesh_allocsize_default[4];
119 /* ob is needed by multires */
120 BMesh *BM_mesh_create(struct Object *ob, const int allocsize[4]);
121 BMesh *BM_mesh_copy(BMesh *bmold);
122 void BM_mesh_free(BMesh *bm);
124 /* frees mesh, but not actual BMesh struct */
125 void BM_mesh_data_free(BMesh *bm);
126 void BM_mesh_normals_update(BMesh *bm, const short skip_hidden);
129 BMVert *BM_vert_create(BMesh *bm, const float co[3], const BMVert *example);
130 BMEdge *BM_edge_create(BMesh *bm, BMVert *v1, BMVert *v2, const BMEdge *example, int nodouble);
131 BMFace *BM_face_create(BMesh *bm, BMVert **verts, BMEdge **edges, const int len, int nodouble);
133 BMFace *BM_face_create_quad_tri_v(BMesh *bm,
134 BMVert **verts, int len,
135 const BMFace *example, const int nodouble);
137 /* easier to use version of BM_face_create_quad_tri_v.
138 * creates edges if necassary. */
139 BMFace *BM_face_create_quad_tri(BMesh *bm, BMVert *v1, BMVert *v2, BMVert *v3, BMVert *v4,
140 const BMFace *example, const int nodouble);
142 /* makes an ngon from an unordered list of edges. v1 and v2 must be the verts
143 * defining edges[0], and define the winding of the new face. */
144 BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, int len, int nodouble);
146 /* stuff for dealing with header flags */
147 BM_INLINE char BM_elem_flag_test(const void *element, const char hflag);
149 /* stuff for dealing with header flags */
150 BM_INLINE void BM_elem_flag_enable(void *element, const char hflag);
152 /* stuff for dealing with header flags */
153 BM_INLINE void BM_elem_flag_disable(void *element, const char hflag);
155 /* stuff for dealing BM_elem_flag_toggle header flags */
156 BM_INLINE void BM_elem_flag_toggle(void *element, const char hflag);
157 BM_INLINE void BM_elem_flag_merge(void *element_a, void *element_b);
159 /* notes on BM_elem_index_set(...) usage,
160 * Set index is sometimes abused as temp storage, other times we cant be
161 * sure if the index values are valid because certain operations have modified
162 * the mesh structure.
164 * To set the elements to valid indicies 'BM_mesh_elem_index_ensure' should be used
165 * rather then adding inline loops, however there are cases where we still
166 * set the index directly
168 * In an attempt to manage this, here are 3 tags Im adding to uses of
169 * 'BM_elem_index_set'
171 * - 'set_inline' -- since the data is already being looped over set to a
172 * valid value inline.
174 * - 'set_dirty!' -- intentionally sets the index to an invalid value,
175 * flagging 'bm->elem_index_dirty' so we dont use it.
177 * - 'set_ok' -- this is valid use since the part of the code is low level.
179 * - 'set_ok_invalid' -- set to -1 on purpose since this should not be
180 * used without a full array re-index, do this on
181 * adding new vert/edge/faces since they may be added at
182 * the end of the array.
184 * - 'set_loop' -- currently loop index values are not used used much so
185 * assume each case they are dirty.
188 BM_INLINE void BM_elem_index_set(void *element, const int index);
189 BM_INLINE int BM_elem_index_get(const void *element);
192 BMFace *BM_face_copy(BMesh *bm, BMFace *f, const short copyverts, const short copyedges);
194 /* copies loop data from adjacent faces */
195 void BM_face_copy_shared(BMesh *bm, BMFace *f);
197 /* copies attributes, e.g. customdata, header flags, etc, from one element
198 * to another of the same type.*/
199 void BM_elem_attrs_copy(BMesh *source_mesh, BMesh *target_mesh, const void *source, void *target);
202 /* join two adjacent faces together along an edge. note that
203 * the faces must only be joined by on edge. e is the edge you
204 * wish to dissolve.*/
205 BMFace *BM_faces_join_pair(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e);
207 /* generic, flexible join faces function; note that most everything uses
208 * this, including BM_faces_join_pair */
209 BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface);
211 /* split a face along two vertices. returns the newly made face, and sets
212 * the nl member to a loop in the newly created edge.*/
213 BMFace *BM_face_split(BMesh *bm, BMFace *f,
214 BMVert *v1, BMVert *v2,
215 struct BMLoop **nl, BMEdge *example);
217 /* these 2 functions are very similar */
218 BMEdge* BM_vert_collapse_faces(BMesh *bm, BMEdge *ke, BMVert *kv, float fac, const int join_faces);
219 BMEdge* BM_vert_collapse_edge(BMesh *bm, BMEdge *ke, BMVert *kv);
222 /* splits an edge. ne is set to the new edge created. */
223 BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **ne, float percent);
225 /* split an edge multiple times evenly */
226 BMVert *BM_edge_split_n(BMesh *bm, BMEdge *e, int numcuts);
228 /* connect two verts together, through a face they share. this function may
229 * be removed in the future. */
230 BMEdge *BM_verts_connect(BMesh *bm, BMVert *v1, BMVert *v2, BMFace **nf);
232 /* rotates an edge topologically, either clockwise (if ccw=0) or counterclockwise
234 BMEdge *BM_edge_rotate(BMesh *bm, BMEdge *e, int ccw);
236 /* Rip a single face from a vertex fan */
237 BMVert *BM_vert_rip(BMesh *bm, BMFace *sf, BMVert *sv);
239 /*updates a face normal*/
240 void BM_face_normal_update(BMesh *bm, BMFace *f);
241 void BM_face_normal_update_vcos(BMesh *bm, BMFace *f, float no[3], float (*vertexCos)[3]);
243 /*updates face and vertex normals incident on an edge*/
244 void BM_edge_normals_update(BMesh *bm, BMEdge *e);
246 /*update a vert normal (but not the faces incident on it)*/
247 void BM_vert_normal_update(BMesh *bm, BMVert *v);
248 void BM_vert_normal_update_all(BMesh *bm, BMVert *v);
250 void BM_face_normal_flip(BMesh *bm, BMFace *f);
252 /*dissolves all faces around a vert, and removes it.*/
253 int BM_disk_dissolve(BMesh *bm, BMVert *v);
255 /* dissolves vert, in more situations then BM_disk_dissolve
256 * (e.g. if the vert is part of a wire edge, etc).*/
257 int BM_vert_dissolve(BMesh *bm, BMVert *v);
259 /* Projects co onto face f, and returns true if it is inside
260 * the face bounds. Note that this uses a best-axis projection
261 * test, instead of projecting co directly into f's orientation
262 * space, so there might be accuracy issues.*/
263 int BM_face_point_inside_test(BMesh *bm, BMFace *f, const float co[3]);
267 /* projects target onto source for customdata interpolation. note: only
268 * does loop customdata. multires is handled. */
269 void BM_face_interp_from_face(BMesh *bm, BMFace *target, BMFace *source);
271 /* projects a single loop, target, onto source for customdata interpolation. multires is handled.
272 * if do_vertex is true, target's vert data will also get interpolated.*/
273 void BM_loop_interp_from_face(BMesh *bm, BMLoop *target, BMFace *source,
274 int do_vertex, int do_multires);
276 /* smoothes boundaries between multires grids, including some borders in adjacent faces */
277 void BM_face_multires_bounds_smooth(BMesh *bm, BMFace *f);
279 /* project the multires grid in target onto source's set of multires grids */
280 void BM_loop_interp_multires(BMesh *bm, BMLoop *target, BMFace *source);
281 void BM_vert_interp_from_face(BMesh *bm, BMVert *v, BMFace *source);
283 void BM_data_interp_from_verts(BMesh *bm, BMVert *v1, BMVert *v2, BMVert *v, const float fac);
284 void BM_data_interp_face_vert_edge(BMesh *bm, BMVert *v1, BMVert *v2, BMVert *v, struct BMEdge *e1, const float fac);
285 void BM_data_layer_add(BMesh *em, CustomData *data, int type);
286 void BM_data_layer_add_named(BMesh *bm, CustomData *data, int type, const char *name);
287 void BM_data_layer_free(BMesh *em, CustomData *data, int type);
288 void BM_data_layer_free_n(BMesh *bm, CustomData *data, int type, int n);
289 float BM_elem_float_data_get(struct CustomData *cd, void *element, int type);
290 void BM_elem_float_data_set(struct CustomData *cd, void *element, int type, const float val);
292 /* get the area of the face */
293 float BM_face_area_calc(BMesh *bm, BMFace *f);
294 /* computes the centroid of a face, using the center of the bounding box */
295 void BM_face_center_bounds_calc(BMesh *bm, BMFace *f, float center[3]);
296 /* computes the centroid of a face, using the mean average */
297 void BM_face_center_mean_calc(BMesh *bm, BMFace *f, float center[3]);
299 void BM_mesh_select_mode_flush(BMesh *bm);
301 /* mode independent flushing up/down */
302 void BM_mesh_deselect_flush(BMesh *bm);
303 void BM_mesh_select_flush(BMesh *bm);
305 /* flag conversion funcs */
306 char BM_face_flag_from_mflag(const char mflag);
307 char BM_edge_flag_from_mflag(const short mflag);
308 char BM_vert_flag_from_mflag(const char mflag);
310 char BM_face_flag_to_mflag(BMFace *f);
311 short BM_edge_flag_to_mflag(BMEdge *e);
312 char BM_vert_flag_to_mflag(BMVert *v);
315 /* convert MLoop*** in a bmface to mtface and mcol in
317 void BM_loops_to_corners(BMesh *bm, struct Mesh *me, int findex,
318 BMFace *f, int numTex, int numCol);
320 void BM_loop_kill(BMesh *bm, BMLoop *l);
321 void BM_face_kill(BMesh *bm, BMFace *f);
322 void BM_edge_kill(BMesh *bm, BMEdge *e);
323 void BM_vert_kill(BMesh *bm, BMVert *v);
325 /* kills all edges associated with f, along with any other faces containing
327 void BM_face_edges_kill(BMesh *bm, BMFace *f);
329 /* kills all verts associated with f, along with any other faces containing
331 void BM_face_verts_kill(BMesh *bm, BMFace *f);
333 /*clear all data in bm*/
334 void BM_mesh_clear(BMesh *bm);
336 void BM_mesh_elem_index_ensure(BMesh *bm, const char hflag);
338 void BM_mesh_elem_index_validate(BMesh *bm, const char *location, const char *func,
339 const char *msg_a, const char *msg_b);
341 BMVert *BM_vert_at_index(BMesh *bm, const int index);
342 BMEdge *BM_edge_at_index(BMesh *bm, const int index);
343 BMFace *BM_face_at_index(BMesh *bm, const int index);
346 void bmesh_begin_edit(BMesh *bm, int flag);
347 void bmesh_end_edit(BMesh *bm, int flag);
350 #ifdef USE_BMESH_HOLES
351 # define BM_FACE_FIRST_LOOP(p) (((BMLoopList *)((p)->loops.first))->first)
353 # define BM_FACE_FIRST_LOOP(p) ((p)->l_first)
356 /* size to use for static arrays when dealing with NGons,
357 * alloc after this limit is reached.
358 * this value is rather arbitrary */
359 #define BM_NGON_STACK_SIZE 32
361 /* avoid inf loop, this value is arbtrary
362 * but should not error on valid cases */
363 #define BM_LOOP_RADIAL_MAX 10000
364 #define BM_NGON_MAX 100000
366 /* include the rest of the API */
367 #include "bmesh_marking.h"
368 #include "bmesh_operator_api.h"
369 #include "bmesh_operators.h"
370 #include "bmesh_error.h"
371 #include "bmesh_queries.h"
372 #include "bmesh_iterators.h"
373 #include "bmesh_walkers.h"
374 #include "intern/bmesh_inline.c"
380 #endif /* __BMESH_H__ */