diff options
Diffstat (limited to 'source/blender/bmesh/bmesh.h')
-rw-r--r-- | source/blender/bmesh/bmesh.h | 372 |
1 files changed, 372 insertions, 0 deletions
diff --git a/source/blender/bmesh/bmesh.h b/source/blender/bmesh/bmesh.h new file mode 100644 index 00000000000..80bdc8e4713 --- /dev/null +++ b/source/blender/bmesh/bmesh.h @@ -0,0 +1,372 @@ +/* + * BMesh API. + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Geoffrey Bantle, Levi Schooley. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef BMESH_H +#define BMESH_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "DNA_listBase.h" +#include "DNA_scene_types.h" +#include "DNA_customdata_types.h" + +#include "BKE_customdata.h" + +#include "BLI_utildefines.h" + +/* +short introduction: + +the bmesh structure is a boundary representation, supporting non-manifold +locally modifiable topology. the API is designed to allow clean, maintainable +code, that never (or almost never) directly inspects the underlying structure. + +The API includes iterators, including many useful topological iterators; +walkers, which walk over a mesh, without the risk of hitting the recursion +limit; operators, which are logical, reusable mesh modules; topological +modification functions (like split face, join faces, etc), which are used for +topological manipulations; and some (not yet finished) geometric utility +functions. + +some definitions: + +tool flags: private flags for tools. each operator has it's own private + tool flag "layer", which it can use to flag elements. + tool flags are also used by various other parts of the api. +header flags: stores persistent flags, such as selection state, hide state, + etc. be careful of touching these. +*/ + +/*forward declarations*/ +struct BMesh; +struct BMVert; +struct BMEdge; +struct BMFace; +struct BMLoop; +struct BMOperator; +struct Mesh; +struct EditMesh; + +/* + * BMHeader + * + * All mesh elements begin with a BMHeader. This structure + * hold several types of data + * + * 1: The type of the element (vert, edge, loop or face) + * 2: Persistant "header" flags/markings (sharp, seam, select, hidden, ect) + note that this is different from the "tool" flags. + * 3: Unique ID in the bmesh. + * 4: some elements for internal record keeping. + * +*/ + +/*BMHeader->htype (char) */ +#define BM_VERT 1 +#define BM_EDGE 2 +#define BM_LOOP 4 +#define BM_FACE 8 +#define BM_ALL (BM_VERT | BM_EDGE | BM_LOOP | BM_FACE) + +/*BMHeader->hflag (char, all bits used!) */ +#define BM_SELECT (1<<0) + +#define BM_SEAM (1<<1) +#define BM_FGON (1<<2) +#define BM_HIDDEN (1<<3) +#define BM_SHARP (1<<4) +#define BM_SMOOTH (1<<5) +#define BM_ACTIVE (1<<6) +#define BM_TMP_TAG (1<<7) /* internal flag, used for ensuring correct normals + * during multires interpolation, and any other time + * when temp tagging is handy. + * always assume dirty & clear before use. */ + +/* #define BM_NONORMCALC (1<<8) */ /* UNUSED */ + +#include "bmesh_class.h" + +/*stub */ +void bmesh_error ( void ); + +/*Mesh Level Ops */ + +/*ob is needed by multires*/ +struct BMesh *BM_Make_Mesh (struct Object *ob, int allocsize[4] ); +BMesh *BM_Copy_Mesh ( BMesh *bmold ); +void BM_Free_Mesh ( struct BMesh *bm ); + +/*frees mesh, but not actual BMesh struct*/ +void BM_Free_Mesh_Data ( BMesh *bm ); +void BM_Compute_Normals ( struct BMesh *bm ); + +/*Construction*/ +struct BMVert *BM_Make_Vert ( struct BMesh *bm, const float co[3], const struct BMVert *example ); +struct BMEdge *BM_Make_Edge ( struct BMesh *bm, struct BMVert *v1, struct BMVert *v2, const struct BMEdge *example, int nodouble ); +struct BMFace *BM_Make_Quadtriangle ( struct BMesh *bm, struct BMVert **verts, BMEdge **edges, int len, const struct BMFace *example, int nodouble ); + +BMFace *BM_Make_Face(BMesh *bm, BMVert **verts, BMEdge **edges, const int len, int nodouble); + +/*more easier to use version of BM_Make_Quadtriangle. + creates edges if necassary.*/ +BMFace *BM_Make_QuadTri ( BMesh *bm, BMVert *v1, BMVert *v2, BMVert *v3, + BMVert *v4, const BMFace *example, int nodouble ); + +/*makes an ngon from an unordered list of edges. v1 and v2 must be the verts +defining edges[0], and define the winding of the new face.*/ +struct BMFace *BM_Make_Ngon ( struct BMesh *bm, struct BMVert *v1, struct BMVert *v2, struct BMEdge **edges, int len, int nodouble ); + +/*stuff for dealing with header flags*/ +BM_INLINE char BM_TestHFlag(const void *element, const char hflag); + +/*stuff for dealing with header flags*/ +BM_INLINE void BM_SetHFlag(void *element, const char hflag); + +/*stuff for dealing with header flags*/ +BM_INLINE void BM_ClearHFlag(void *element, const char hflag); + +/*stuff for dealing BM_ToggleHFlag header flags*/ +BM_INLINE void BM_ToggleHFlag(void *element, const char hflag); +BM_INLINE void BM_MergeHFlag(void *element_a, void *element_b); + +/* notes on BM_SetIndex(...) usage, + * Set index is sometimes abused as temp storage, other times we cant be + * sure if the index values are valid because certain operations have modified + * the mesh structure. + * + * To set the elements to valid indicies 'BM_ElemIndex_Ensure' should be used + * rather then adding inline loops, however there are cases where we still + * set the index directly + * + * In an attempt to manage this, here are 3 tags Im adding to uses of + * 'BM_SetIndex' + * + * - 'set_inline' -- since the data is already being looped over set to a + * valid value inline. + * + * - 'set_dirty!' -- intentionally sets the index to an invalid value, + * flagging 'bm->elem_index_dirty' so we dont use it. + * + * - 'set_ok' -- this is valid use since the part of the code is low level. + * + * - 'set_ok_invalid' -- set to -1 on purpose since this should not be + * used without a full array re-index, do this on + * adding new vert/edge/faces since they may be added at + * the end of the array. + * + * - 'set_loop' -- currently loop index values are not used used much so + * assume each case they are dirty. + * - campbell */ + +BM_INLINE void BM_SetIndex(void *element, const int index); +BM_INLINE int BM_GetIndex(const void *element); + +/*copies loop data from adjacent faces*/ +void BM_Face_CopyShared ( BMesh *bm, BMFace *f ); + +/*copies attributes, e.g. customdata, header flags, etc, from one element + to another of the same type.*/ +void BM_Copy_Attributes ( struct BMesh *source_mesh, struct BMesh *target_mesh, const void *source, void *target ); + +/*Modification*/ +/*join two adjacent faces together along an edge. note that + the faces must only be joined by on edge. e is the edge you + wish to dissolve.*/ +BMFace *BM_Join_TwoFaces(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e); + +/*generic, flexible join faces function; note that most everything uses + this, including BM_Join_TwoFaces*/ +BMFace *BM_Join_Faces(BMesh *bm, BMFace **faces, int totface); + +/*split a face along two vertices. returns the newly made face, and sets + the nl member to a loop in the newly created edge.*/ +struct BMFace *BM_Split_Face ( struct BMesh *bm, struct BMFace *f, + struct BMVert *v1, struct BMVert *v2, + struct BMLoop **nl, struct BMEdge *example ); + +/*dissolves a vert shared only by two edges*/ +BMEdge* BM_Collapse_Vert ( struct BMesh *bm, struct BMEdge *ke, struct BMVert *kv, + float fac ); + +/*splits an edge. ne is set to the new edge created.*/ +struct BMVert *BM_Split_Edge ( struct BMesh *bm, struct BMVert *v, + struct BMEdge *e, struct BMEdge **ne, + float percent ); + +/*split an edge multiple times evenly*/ +struct BMVert *BM_Split_Edge_Multi ( struct BMesh *bm, struct BMEdge *e, + int numcuts ); + +/*connect two verts together, through a face they share. this function may + be removed in the future.*/ +BMEdge *BM_Connect_Verts ( BMesh *bm, BMVert *v1, BMVert *v2, BMFace **nf ); + +/*rotates an edge topologically, either clockwise (if ccw=0) or counterclockwise + (if ccw is 1).*/ +BMEdge *BM_Rotate_Edge ( BMesh *bm, BMEdge *e, int ccw ); + +/* Rip a single face from a vertex fan */ +BMVert *BM_Rip_Vertex ( BMesh *bm, BMFace *sf, BMVert *sv); + +/*updates a face normal*/ +void BM_Face_UpdateNormal ( BMesh *bm, BMFace *f ); + +/*updates face and vertex normals incident on an edge*/ +void BM_Edge_UpdateNormals ( BMesh *bm, BMEdge *e ); + +/*update a vert normal (but not the faces incident on it)*/ +void BM_Vert_UpdateNormal ( BMesh *bm, BMVert *v ); +void BM_Vert_UpdateAllNormals ( BMesh *bm, BMVert *v ); + +void BM_flip_normal ( BMesh *bm, BMFace *f ); + +/*dissolves all faces around a vert, and removes it.*/ +int BM_Dissolve_Disk ( BMesh *bm, BMVert *v ); + +/*dissolves vert, in more situations then BM_Dissolve_Disk + (e.g. if the vert is part of a wire edge, etc).*/ +int BM_Dissolve_Vert ( BMesh *bm, BMVert *v ); + +/*Projects co onto face f, and returns true if it is inside + the face bounds. Note that this uses a best-axis projection + test, instead of projecting co directly into f's orientation + space, so there might be accuracy issues.*/ +int BM_Point_In_Face(BMesh *bm, BMFace *f, float co[3]); + +/*Interpolation*/ + +/*projects target onto source for customdata interpolation. note: only + does loop customdata. multires is handled. */ +void BM_face_interp_from_face(BMesh *bm, BMFace *target, BMFace *source); + +/*projects a single loop, target, onto source for customdata interpolation. multires is handled. + if do_vertex is true, target's vert data will also get interpolated.*/ +void BM_loop_interp_from_face(BMesh *bm, BMLoop *target, BMFace *source, + int do_vertex, int do_multires); + +/*smoothes boundaries between multires grids, including some borders in adjacent faces*/ +void BM_multires_smooth_bounds(BMesh *bm, BMFace *f); + +/*project the multires grid in target onto source's set of multires grids*/ +void BM_loop_interp_multires(BMesh *bm, BMLoop *target, BMFace *source); +void BM_vert_interp_from_face(BMesh *bm, BMVert *v, BMFace *source); + +void BM_Data_Interp_From_Verts (struct BMesh *bm, struct BMVert *v1, struct BMVert *v2, struct BMVert *v, float fac); +void BM_Data_Facevert_Edgeinterp (struct BMesh *bm, struct BMVert *v1, struct BMVert *v2, struct BMVert *v, struct BMEdge *e1, float fac); +void BM_add_data_layer (BMesh *em, CustomData *data, int type); +void BM_add_data_layer_named (BMesh *bm, CustomData *data, int type, const char *name); +void BM_free_data_layer (BMesh *em, CustomData *data, int type ); +void BM_free_data_layer_n(BMesh *bm, CustomData *data, int type, int n); +float BM_GetCDf(struct CustomData *cd, void *element, int type); +void BM_SetCDf(struct CustomData *cd, void *element, int type, float val); + +/*computes the centroid of a face, using the center of the bounding box*/ +void BM_Compute_Face_CenterBounds(BMesh *bm, BMFace *f, float center[3]); +/*computes the centroid of a face, using the mean average*/ +void BM_Compute_Face_CenterMean(BMesh *bm, BMFace *f, float center[3]); + +void BM_SelectMode_Flush ( BMesh *bm ); + +/*convert an editmesh to a bmesh*/ +BMesh *editmesh_to_bmesh ( struct EditMesh *em ); + +/*initializes editmesh to bmesh operator, but doesn't execute. + this is used in situations where you need to get access to the + conversion operator's editmesh->bmesh mapping slot (e.g. if you + need to find the bmesh edge that corrusponds to a specific editmesh + edge).*/ +BMesh *init_editmesh_to_bmesh ( struct EditMesh *em, struct BMOperator *op ); + +/*converts a bmesh to an editmesh*/ +struct EditMesh *bmesh_to_editmesh ( BMesh *bm ); + +/*convert between bmesh and Mesh flags*/ +short BMFlags_To_MEFlags(void *element); + +/*convert between Mesh and bmesh flags + type must be BM_VERT/BM_EDGE/BM_FACE, + and represents the type of the element + parameter (the three defines map to + MVert, MEdge, and MPoly, respectively).*/ +char MEFlags_To_BMFlags(const short hflag, const char htype); + +/*convert MLoop*** in a bmface to mtface and mcol in + an MFace*/ +void BM_loops_to_corners ( BMesh *bm, struct Mesh *me, int findex, + BMFace *f, int numTex, int numCol ); + +void BM_Kill_Loop(BMesh *bm, BMLoop *l); +void BM_Kill_Face(BMesh *bm, BMFace *f); +void BM_Kill_Edge(BMesh *bm, BMEdge *e); +void BM_Kill_Vert(BMesh *bm, BMVert *v); + +/*kills all edges associated with f, along with any other faces containing + those edges*/ +void BM_Kill_Face_Edges(BMesh *bm, BMFace *f); + +/*kills all verts associated with f, along with any other faces containing + those vertices*/ +void BM_Kill_Face_Verts(BMesh *bm, BMFace *f) ; + +/*clear all data in bm*/ +void BM_Clear_Mesh(BMesh *bm); + +void BM_ElemIndex_Ensure(BMesh *bm, const char hflag); + +void BM_ElemIndex_Validate(BMesh *bm, const char *location, const char *func, const char *msg_a, const char *msg_b); + +BMVert *BM_Vert_AtIndex(BMesh *bm, const int index); +BMEdge *BM_Edge_AtIndex(BMesh *bm, const int index); +BMFace *BM_Face_AtIndex(BMesh *bm, const int index); + +/*start/stop edit*/ +void bmesh_begin_edit(struct BMesh *bm, int flag); +void bmesh_end_edit(struct BMesh *bm, int flag); + + +#define bm_firstfaceloop(p) ((BMLoopList*)(p->loops.first))->first + +/* size to use for static arrays when dealing with NGons, + * alloc after this limit is reached. + * this value is rather arbitrary */ +#define BM_NGON_STACK_SIZE 32 + +/*include the rest of the API*/ +#include "bmesh_filters.h" +#include "bmesh_iterators.h" +#include "bmesh_marking.h" +#include "bmesh_operator_api.h" +#include "bmesh_operators.h" +#include "bmesh_error.h" +#include "bmesh_queries.h" +#include "bmesh_walkers.h" +#include "intern/bmesh_inline.c" + +#ifdef __cplusplus +} +#endif + +#endif /* BMESH_H */ |