Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/bmesh/intern/bmesh_core.h')
-rw-r--r--source/blender/bmesh/intern/bmesh_core.h290
1 files changed, 286 insertions, 4 deletions
diff --git a/source/blender/bmesh/intern/bmesh_core.h b/source/blender/bmesh/intern/bmesh_core.h
index 8f7580714ae..cd0e1754cd1 100644
--- a/source/blender/bmesh/intern/bmesh_core.h
+++ b/source/blender/bmesh/intern/bmesh_core.h
@@ -25,26 +25,50 @@ BMFace *BM_face_copy(
typedef enum eBMCreateFlag {
BM_CREATE_NOP = 0,
- /* faces and edges only */
+ /** Faces and edges only. */
BM_CREATE_NO_DOUBLE = (1 << 1),
- /* Skip CustomData - for all element types data,
- * use if we immediately write customdata into the element so this skips copying from 'example'
- * args or setting defaults, speeds up conversion when data is converted all at once. */
+ /**
+ * Skip custom-data - for all element types data,
+ * use if we immediately write custom-data into the element so this skips copying from 'example'
+ * arguments or setting defaults, speeds up conversion when data is converted all at once.
+ */
BM_CREATE_SKIP_CD = (1 << 2),
} eBMCreateFlag;
+/**
+ * \brief Main function for creating a new vertex.
+ */
BMVert *BM_vert_create(BMesh *bm,
const float co[3],
const BMVert *v_example,
const eBMCreateFlag create_flag);
+/**
+ * \brief Main function for creating a new edge.
+ *
+ * \note Duplicate edges are supported by the API however users should _never_ see them.
+ * so unless you need a unique edge or know the edge won't exist,
+ * you should call with \a no_double = true.
+ */
BMEdge *BM_edge_create(
BMesh *bm, BMVert *v1, BMVert *v2, const BMEdge *e_example, const eBMCreateFlag create_flag);
+/**
+ * Main face creation function
+ *
+ * \param bm: The mesh
+ * \param verts: A sorted array of verts size of len
+ * \param edges: A sorted array of edges size of len
+ * \param len: Length of the face
+ * \param create_flag: Options for creating the face
+ */
BMFace *BM_face_create(BMesh *bm,
BMVert **verts,
BMEdge **edges,
const int len,
const BMFace *f_example,
const eBMCreateFlag create_flag);
+/**
+ * Wrapper for #BM_face_create when you don't have an edge array
+ */
BMFace *BM_face_create_verts(BMesh *bm,
BMVert **vert_arr,
const int len,
@@ -52,27 +76,105 @@ BMFace *BM_face_create_verts(BMesh *bm,
const eBMCreateFlag create_flag,
const bool create_edges);
+/**
+ * Kills all edges associated with \a f, along with any other faces containing those edges.
+ */
void BM_face_edges_kill(BMesh *bm, BMFace *f);
+/**
+ * kills all verts associated with \a f, along with any other faces containing
+ * those vertices
+ */
void BM_face_verts_kill(BMesh *bm, BMFace *f);
+/**
+ * A version of #BM_face_kill which removes edges and verts
+ * which have no remaining connected geometry.
+ */
void BM_face_kill_loose(BMesh *bm, BMFace *f);
+/**
+ * Kills \a f and its loops.
+ */
void BM_face_kill(BMesh *bm, BMFace *f);
+/**
+ * Kills \a e and all faces that use it.
+ */
void BM_edge_kill(BMesh *bm, BMEdge *e);
+/**
+ * Kills \a v and all edges that use it.
+ */
void BM_vert_kill(BMesh *bm, BMVert *v);
+/**
+ * \brief Splice Edge
+ *
+ * Splice two unique edges which share the same two vertices into one edge.
+ * (\a e_src into \a e_dst, removing e_src).
+ *
+ * \return Success
+ *
+ * \note Edges must already have the same vertices.
+ */
bool BM_edge_splice(BMesh *bm, BMEdge *e_dst, BMEdge *e_src);
+/**
+ * \brief Splice Vert
+ *
+ * Merges two verts into one
+ * (\a v_src into \a v_dst, removing \a v_src).
+ *
+ * \return Success
+ *
+ * \warning This doesn't work for collapsing edges,
+ * where \a v and \a vtarget are connected by an edge
+ * (assert checks for this case).
+ */
bool BM_vert_splice(BMesh *bm, BMVert *v_dst, BMVert *v_src);
+/**
+ * Check if splicing vertices would create any double edges.
+ *
+ * \note assume caller will handle case where verts share an edge.
+ */
bool BM_vert_splice_check_double(BMVert *v_a, BMVert *v_b);
+/**
+ * \brief Loop Reverse
+ *
+ * Changes the winding order of a face from CW to CCW or vice versa.
+ *
+ * \param cd_loop_mdisp_offset: Cached result of `CustomData_get_offset(&bm->ldata, CD_MDISPS)`.
+ * \param use_loop_mdisp_flip: When set, flip the Z-depth of the mdisp,
+ * (use when flipping normals, disable when mirroring, eg: symmetrize).
+ */
void bmesh_kernel_loop_reverse(BMesh *bm,
BMFace *f,
const int cd_loop_mdisp_offset,
const bool use_loop_mdisp_flip);
+/**
+ * Avoid calling this where possible,
+ * low level function so both face pointers remain intact but point to swapped data.
+ * \note must be from the same bmesh.
+ */
void bmesh_face_swap_data(BMFace *f_a, BMFace *f_b);
+/**
+ * \brief Join Connected Faces
+ *
+ * Joins a collected group of faces into one. Only restriction on
+ * the input data is that the faces must be connected to each other.
+ *
+ * \return The newly created combine BMFace.
+ *
+ * \note If a pair of faces share multiple edges,
+ * the pair of faces will be joined at every edge.
+ *
+ * \note this is a generic, flexible join faces function,
+ * almost everything uses this, including #BM_faces_join_pair
+ */
BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface, const bool do_del);
+/**
+ * High level function which wraps both #bmesh_kernel_vert_separate and #bmesh_kernel_edge_separate
+ */
void BM_vert_separate(BMesh *bm,
BMVert *v,
BMEdge **e_in,
@@ -80,6 +182,9 @@ void BM_vert_separate(BMesh *bm,
const bool copy_select,
BMVert ***r_vout,
int *r_vout_len);
+/**
+ * A version of #BM_vert_separate which takes a flag.
+ */
void BM_vert_separate_hflag(BMesh *bm,
BMVert *v,
const char hflag,
@@ -94,10 +199,70 @@ void BM_vert_separate_tested_edges(
*
* Names are on the verbose side but these are only for low-level access.
*/
+/**
+ * \brief Separate Vert
+ *
+ * Separates all disjoint fans that meet at a vertex, making a unique
+ * vertex for each region. returns an array of all resulting vertices.
+ *
+ * \note this is a low level function, bm_edge_separate needs to run on edges first
+ * or, the faces sharing verts must not be sharing edges for them to split at least.
+ *
+ * \return Success
+ */
void bmesh_kernel_vert_separate(
BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len, const bool copy_select);
+/**
+ * \brief Separate Edge
+ *
+ * Separates a single edge into two edge: the original edge and
+ * a new edge that has only \a l_sep in its radial.
+ *
+ * \return Success
+ *
+ * \note Does nothing if \a l_sep is already the only loop in the
+ * edge radial.
+ */
void bmesh_kernel_edge_separate(BMesh *bm, BMEdge *e, BMLoop *l_sep, const bool copy_select);
+/**
+ * \brief Split Face Make Edge (SFME)
+ *
+ * \warning this is a low level function, most likely you want to use #BM_face_split()
+ *
+ * Takes as input two vertices in a single face.
+ * An edge is created which divides the original face into two distinct regions.
+ * One of the regions is assigned to the original face and it is closed off.
+ * The second region has a new face assigned to it.
+ *
+ * \par Examples:
+ * <pre>
+ * Before: After:
+ * +--------+ +--------+
+ * | | | |
+ * | | | f1 |
+ * v1 f1 v2 v1======v2
+ * | | | f2 |
+ * | | | |
+ * +--------+ +--------+
+ * </pre>
+ *
+ * \note the input vertices can be part of the same edge. This will
+ * result in a two edged face. This is desirable for advanced construction
+ * tools and particularly essential for edge bevel. Because of this it is
+ * up to the caller to decide what to do with the extra edge.
+ *
+ * \note If \a holes is NULL, then both faces will lose
+ * all holes from the original face. Also, you cannot split between
+ * a hole vert and a boundary vert; that case is handled by higher-
+ * level wrapping functions (when holes are fully implemented, anyway).
+ *
+ * \note that holes represents which holes goes to the new face, and of
+ * course this requires removing them from the existing face first, since
+ * you cannot have linked list links inside multiple lists.
+ *
+ * \return A BMFace pointer
+ */
BMFace *bmesh_kernel_split_face_make_edge(BMesh *bm,
BMFace *f,
BMLoop *l_v1,
@@ -109,7 +274,55 @@ BMFace *bmesh_kernel_split_face_make_edge(BMesh *bm,
BMEdge *example,
const bool no_double);
+/**
+ * \brief Split Edge Make Vert (SEMV)
+ *
+ * Takes \a e edge and splits it into two, creating a new vert.
+ * \a tv should be one end of \a e : the newly created edge
+ * will be attached to that end and is returned in \a r_e.
+ *
+ * \par Examples:
+ *
+ * <pre>
+ * E
+ * Before: OV-------------TV
+ * E RE
+ * After: OV------NV-----TV
+ * </pre>
+ *
+ * \return The newly created BMVert pointer.
+ */
BMVert *bmesh_kernel_split_edge_make_vert(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e);
+/**
+ * \brief Join Edge Kill Vert (JEKV)
+ *
+ * Takes an edge \a e_kill and pointer to one of its vertices \a v_kill
+ * and collapses the edge on that vertex.
+ *
+ * \par Examples:
+ *
+ * <pre>
+ * Before: e_old e_kill
+ * +-------+-------+
+ * | | |
+ * v_old v_kill v_target
+ *
+ * After: e_old
+ * +---------------+
+ * | |
+ * v_old v_target
+ * </pre>
+ *
+ * \par Restrictions:
+ * KV is a vertex that must have a valance of exactly two. Furthermore
+ * both edges in KV's disk cycle (OE and KE) must be unique (no double edges).
+ *
+ * \return The resulting edge, NULL for failure.
+ *
+ * \note This euler has the possibility of creating
+ * faces with just 2 edges. It is up to the caller to decide what to do with
+ * these faces.
+ */
BMEdge *bmesh_kernel_join_edge_kill_vert(BMesh *bm,
BMEdge *e_kill,
BMVert *v_kill,
@@ -117,14 +330,83 @@ BMEdge *bmesh_kernel_join_edge_kill_vert(BMesh *bm,
const bool check_edge_exists,
const bool kill_degenerate_faces,
const bool kill_duplicate_faces);
+/**
+ * \brief Join Vert Kill Edge (JVKE)
+ *
+ * Collapse an edge, merging surrounding data.
+ *
+ * Unlike #BM_vert_collapse_edge & #bmesh_kernel_join_edge_kill_vert
+ * which only handle 2 valence verts,
+ * this can handle any number of connected edges/faces.
+ *
+ * <pre>
+ * Before: -> After:
+ * +-+-+-+ +-+-+-+
+ * | | | | | \ / |
+ * +-+-+-+ +--+--+
+ * | | | | | / \ |
+ * +-+-+-+ +-+-+-+
+ * </pre>
+ */
BMVert *bmesh_kernel_join_vert_kill_edge(BMesh *bm,
BMEdge *e_kill,
BMVert *v_kill,
const bool do_del,
const bool check_edge_exists,
const bool kill_degenerate_faces);
+/**
+ * \brief Join Face Kill Edge (JFKE)
+ *
+ * Takes two faces joined by a single 2-manifold edge and fuses them together.
+ * The edge shared by the faces must not be connected to any other edges which have
+ * Both faces in its radial cycle
+ *
+ * \par Examples:
+ * <pre>
+ * A B
+ * +--------+ +--------+
+ * | | | |
+ * | f1 | | f1 |
+ * v1========v2 = Ok! v1==V2==v3 == Wrong!
+ * | f2 | | f2 |
+ * | | | |
+ * +--------+ +--------+
+ * </pre>
+ *
+ * In the example A, faces \a f1 and \a f2 are joined by a single edge,
+ * and the euler can safely be used.
+ * In example B however, \a f1 and \a f2 are joined by multiple edges and will produce an error.
+ * The caller in this case should call #bmesh_kernel_join_edge_kill_vert on the extra edges
+ * before attempting to fuse \a f1 and \a f2.
+ *
+ * \note The order of arguments decides whether or not certain per-face attributes are present
+ * in the resultant face. For instance vertex winding, material index, smooth flags,
+ * etc are inherited from \a f1, not \a f2.
+ *
+ * \return A BMFace pointer
+ */
BMFace *bmesh_kernel_join_face_kill_edge(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e);
+/**
+ * \brief Un-glue Region Make Vert (URMV)
+ *
+ * Disconnects a face from its vertex fan at loop \a l_sep
+ *
+ * \return The newly created BMVert
+ *
+ * \note Will be a no-op and return original vertex if only two edges at that vertex.
+ */
BMVert *bmesh_kernel_unglue_region_make_vert(BMesh *bm, BMLoop *l_sep);
+/**
+ * A version of #bmesh_kernel_unglue_region_make_vert that disconnects multiple loops at once.
+ * The loops must all share the same vertex, can be in any order
+ * and are all moved to use a single new vertex - which is returned.
+ *
+ * This function handles the details of finding fans boundaries.
+ */
BMVert *bmesh_kernel_unglue_region_make_vert_multi(BMesh *bm, BMLoop **larr, int larr_len);
+/**
+ * This function assumes l_sep is a part of a larger fan which has already been
+ * isolated by calling #bmesh_kernel_edge_separate to segregate it radially.
+ */
BMVert *bmesh_kernel_unglue_region_make_vert_multi_isolated(BMesh *bm, BMLoop *l_sep);