Blender  V3.3
Macros | Functions
bmesh_core.c File Reference
#include "MEM_guardedalloc.h"
#include "BLI_alloca.h"
#include "BLI_array.h"
#include "BLI_linklist_stack.h"
#include "BLI_math_vector.h"
#include "BLI_utildefines_stack.h"
#include "BLT_translation.h"
#include "DNA_meshdata_types.h"
#include "BKE_customdata.h"
#include "BKE_mesh.h"
#include "bmesh.h"
#include "intern/bmesh_private.h"

Go to the source code of this file.

Macros

#define VERT_VISIT   _FLAG_WALK
 
#define EDGE_VISIT   _FLAG_WALK
 
#define LOOP_VISIT   _FLAG_WALK
 
#define EDGE_VISIT   _FLAG_WALK
 

Functions

BMVertBM_vert_create (BMesh *bm, const float co[3], const BMVert *v_example, const eBMCreateFlag create_flag)
 Main function for creating a new vertex. More...
 
BMEdgeBM_edge_create (BMesh *bm, BMVert *v1, BMVert *v2, const BMEdge *e_example, const eBMCreateFlag create_flag)
 Main function for creating a new edge. More...
 
static BMLoopbm_loop_create (BMesh *bm, BMVert *v, BMEdge *e, BMFace *f, const BMLoop *l_example, const eBMCreateFlag create_flag)
 
static BMLoopbm_face_boundary_add (BMesh *bm, BMFace *f, BMVert *startv, BMEdge *starte, const eBMCreateFlag create_flag)
 
BMFaceBM_face_copy (BMesh *bm_dst, BMesh *bm_src, BMFace *f, const bool copy_verts, const bool copy_edges)
 
BLI_INLINE BMFacebm_face_create__internal (BMesh *bm)
 
BMFaceBM_face_create (BMesh *bm, BMVert **verts, BMEdge **edges, const int len, const BMFace *f_example, const eBMCreateFlag create_flag)
 
BMFaceBM_face_create_verts (BMesh *bm, BMVert **vert_arr, const int len, const BMFace *f_example, const eBMCreateFlag create_flag, const bool create_edges)
 
int bmesh_elem_check (void *element, const char htype)
 
static void bm_kill_only_vert (BMesh *bm, BMVert *v)
 
static void bm_kill_only_edge (BMesh *bm, BMEdge *e)
 
static void bm_kill_only_face (BMesh *bm, BMFace *f)
 
static void bm_kill_only_loop (BMesh *bm, BMLoop *l)
 
void BM_face_edges_kill (BMesh *bm, BMFace *f)
 
void BM_face_verts_kill (BMesh *bm, BMFace *f)
 
void BM_face_kill (BMesh *bm, BMFace *f)
 
void BM_face_kill_loose (BMesh *bm, BMFace *f)
 
void BM_edge_kill (BMesh *bm, BMEdge *e)
 
void BM_vert_kill (BMesh *bm, BMVert *v)
 
static int UNUSED_FUNCTION() bm_loop_length (BMLoop *l)
 
void bmesh_kernel_loop_reverse (BMesh *bm, BMFace *f, const int cd_loop_mdisp_offset, const bool use_loop_mdisp_flip)
 Loop Reverse. More...
 
static void bm_elements_systag_enable (void *veles, int tot, const char api_flag)
 
static void bm_elements_systag_disable (void *veles, int tot, const char api_flag)
 
static int bm_loop_systag_count_radial (BMLoop *l, const char api_flag)
 
static int UNUSED_FUNCTION() bm_vert_systag_count_disk (BMVert *v, const char api_flag)
 
static bool bm_vert_is_manifold_flagged (BMVert *v, const char api_flag)
 
BMFaceBM_faces_join (BMesh *bm, BMFace **faces, int totface, const bool do_del)
 Join Connected Faces. More...
 
static BMFacebm_face_create__sfme (BMesh *bm, BMFace *f_example)
 
BMFacebmesh_kernel_split_face_make_edge (BMesh *bm, BMFace *f, BMLoop *l_v1, BMLoop *l_v2, BMLoop **r_l, BMEdge *e_example, const bool no_double)
 Split Face Make Edge (SFME) More...
 
BMVertbmesh_kernel_split_edge_make_vert (BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e)
 Split Edge Make Vert (SEMV) More...
 
BMEdgebmesh_kernel_join_edge_kill_vert (BMesh *bm, BMEdge *e_kill, BMVert *v_kill, const bool do_del, const bool check_edge_exists, const bool kill_degenerate_faces, const bool kill_duplicate_faces)
 Join Edge Kill Vert (JEKV) More...
 
BMVertbmesh_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)
 Join Vert Kill Edge (JVKE) More...
 
BMFacebmesh_kernel_join_face_kill_edge (BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e)
 Join Face Kill Edge (JFKE) More...
 
bool BM_vert_splice_check_double (BMVert *v_a, BMVert *v_b)
 
bool BM_vert_splice (BMesh *bm, BMVert *v_dst, BMVert *v_src)
 Splice Vert. More...
 
bool BM_edge_splice (BMesh *bm, BMEdge *e_dst, BMEdge *e_src)
 Splice Edge. More...
 
void bmesh_kernel_edge_separate (BMesh *bm, BMEdge *e, BMLoop *l_sep, const bool copy_select)
 Separate Edge. More...
 
BMVertbmesh_kernel_unglue_region_make_vert (BMesh *bm, BMLoop *l_sep)
 Un-glue Region Make Vert (URMV) More...
 
BMVertbmesh_kernel_unglue_region_make_vert_multi (BMesh *bm, BMLoop **larr, int larr_len)
 
static void bmesh_edge_vert_swap__recursive (BMEdge *e, BMVert *v_dst, BMVert *v_src)
 
BMVertbmesh_kernel_unglue_region_make_vert_multi_isolated (BMesh *bm, BMLoop *l_sep)
 
void bmesh_face_swap_data (BMFace *f_a, BMFace *f_b)
 
BM_vert_separate, bmesh_kernel_vert_separate and friends
BLI_INLINE bool bm_edge_supports_separate (const BMEdge *e)
 
void bmesh_kernel_vert_separate (BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len, const bool copy_select)
 Separate Vert. More...
 
static void bmesh_kernel_vert_separate__cleanup (BMesh *bm, LinkNode *edges_separate)
 
void BM_vert_separate (BMesh *bm, BMVert *v, BMEdge **e_in, int e_in_len, const bool copy_select, BMVert ***r_vout, int *r_vout_len)
 
void BM_vert_separate_hflag (BMesh *bm, BMVert *v, const char hflag, const bool copy_select, BMVert ***r_vout, int *r_vout_len)
 
void BM_vert_separate_tested_edges (BMesh *UNUSED(bm), BMVert *v_dst, BMVert *v_src, bool(*testfn)(BMEdge *, void *arg), void *arg)
 

Detailed Description

Core BMesh functions for adding, removing BMesh elements.

Definition in file bmesh_core.c.

Macro Definition Documentation

◆ EDGE_VISIT [1/2]

#define EDGE_VISIT   _FLAG_WALK

◆ EDGE_VISIT [2/2]

#define EDGE_VISIT   _FLAG_WALK

◆ LOOP_VISIT

#define LOOP_VISIT   _FLAG_WALK

◆ VERT_VISIT

#define VERT_VISIT   _FLAG_WALK

Function Documentation

◆ BM_edge_create()

BMEdge* BM_edge_create ( BMesh bm,
BMVert v1,
BMVert v2,
const BMEdge e_example,
eBMCreateFlag  create_flag 
)

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 no_double = true.

Definition at line 123 of file bmesh_core.c.

References BMHeader::api_flag, BLI_assert, BLI_mempool_alloc(), BLI_mempool_calloc(), bm, BM_CHECK_ELEMENT, BM_CREATE_NO_DOUBLE, BM_CREATE_SKIP_CD, BM_EDGE, BM_edge_exists(), BM_elem_attrs_copy(), BM_ELEM_DRAW, BM_elem_index_set, BM_ELEM_SMOOTH, BM_SPACEARR_DIRTY_ALL, BM_VERT, bmesh_disk_edge_append(), CustomData_bmesh_set_default(), BMHeader::data, e, BMesh::edata, BMesh::elem_index_dirty, BMesh::elem_table_dirty, BMesh::epool, BMesh::etoolflagpool, BMVert::head, BMEdge::head, BMHeader::hflag, BMHeader::htype, NULL, BMesh::spacearr_dirty, BMesh::totedge, BMesh::use_toolflags, v1, and v2.

Referenced by bevel_reattach_wires(), bevel_vert_two_edges(), BKE_mesh_remesh_voxel_fix_poles(), bm_edge_copy_with_arrays(), BM_edge_rotate(), bm_edges_from_tri(), BM_edges_from_verts_ensure(), BM_face_copy(), BM_face_create_ngon_verts(), BM_face_split_edgenet_connect_islands(), bm_isect_tri_tri(), BM_mesh_bm_from_me(), BM_mesh_copy(), BM_mesh_intersect_edges(), bm_vert_connect_select_history(), bmesh_kernel_edge_separate(), bmesh_kernel_split_edge_make_vert(), bmesh_kernel_split_face_make_edge(), bmesh_kernel_unglue_region_make_vert_multi(), bmo_contextual_create_exec(), bmo_create_circle_exec(), bmo_create_uvsphere_exec(), bmo_edge_copy(), bmo_edgenet_prepare_exec(), bmo_extrude_face_region_exec(), bmo_extrude_vert_indiv_exec(), bmo_face_inset_individual(), bmo_inset_region_exec(), bmo_weld_verts_exec(), bpy_bmedgeseq_new(), edbm_polybuild_face_at_cursor_invoke(), edbm_rip_invoke__vert(), knife_make_face_cuts(), and pbvh_bmesh_split_edge().

◆ BM_edge_kill()

void BM_edge_kill ( BMesh bm,
BMEdge e 
)

◆ BM_edge_splice()

bool BM_edge_splice ( BMesh bm,
BMEdge e_dst,
BMEdge e_src 
)

Splice Edge.

Splice two unique edges which share the same two vertices into one edge. (e_src into e_dst, removing e_src).

Returns
Success
Note
Edges must already have the same vertices.

Definition at line 2332 of file bmesh_core.c.

References BLI_assert, bm, BM_CHECK_ELEMENT, BM_edge_kill(), BM_vert_in_edge(), bmesh_radial_length(), bmesh_radial_loop_append(), bmesh_radial_loop_remove(), BMEdge::l, l, BMLoop::next, BMLoop::v, BMEdge::v1, and BMEdge::v2.

Referenced by bm_edge_collapse(), bmesh_kernel_join_edge_kill_vert(), bmesh_kernel_join_vert_kill_edge(), bmesh_kernel_vert_separate__cleanup(), and bmo_spin_exec().

◆ bm_edge_supports_separate()

BLI_INLINE bool bm_edge_supports_separate ( const BMEdge e)

Definition at line 2077 of file bmesh_core.c.

References e.

Referenced by BM_vert_separate(), and BM_vert_separate_hflag().

◆ bm_elements_systag_disable()

static void bm_elements_systag_disable ( void veles,
int  tot,
const char  api_flag 
)
static

Definition at line 1051 of file bmesh_core.c.

References BM_ELEM_API_FLAG_DISABLE.

Referenced by BM_faces_join().

◆ bm_elements_systag_enable()

static void bm_elements_systag_enable ( void veles,
int  tot,
const char  api_flag 
)
static

Definition at line 1041 of file bmesh_core.c.

References BM_ELEM_API_FLAG_ENABLE.

Referenced by BM_faces_join().

◆ bm_face_boundary_add()

static BMLoop* bm_face_boundary_add ( BMesh bm,
BMFace f,
BMVert startv,
BMEdge starte,
const eBMCreateFlag  create_flag 
)
static

◆ BM_face_copy()

BMFace* BM_face_copy ( BMesh bm_dst,
BMesh bm_src,
BMFace f,
const bool  copy_verts,
const bool  copy_edges 
)

◆ BM_face_create()

BMFace* BM_face_create ( BMesh bm,
BMVert **  verts,
BMEdge **  edges,
int  len,
const BMFace f_example,
eBMCreateFlag  create_flag 
)

◆ bm_face_create__internal()

BLI_INLINE BMFace* bm_face_create__internal ( BMesh bm)

◆ bm_face_create__sfme()

static BMFace* bm_face_create__sfme ( BMesh bm,
BMFace f_example 
)
static

◆ BM_face_create_verts()

BMFace* BM_face_create_verts ( BMesh bm,
BMVert **  vert_arr,
int  len,
const BMFace f_example,
eBMCreateFlag  create_flag,
bool  create_edges 
)

◆ BM_face_edges_kill()

void BM_face_edges_kill ( BMesh bm,
BMFace f 
)

Kills all edges associated with f, along with any other faces containing those edges.

Definition at line 794 of file bmesh_core.c.

References BLI_array_alloca, bm, BM_edge_kill(), BM_FACE_FIRST_LOOP, BMLoop::e, BMFace::len, and BMLoop::next.

◆ BM_face_kill()

void BM_face_kill ( BMesh bm,
BMFace f 
)

◆ BM_face_kill_loose()

void BM_face_kill_loose ( BMesh bm,
BMFace f 
)

A version of BM_face_kill which removes edges and verts which have no remaining connected geometry.

Definition at line 872 of file bmesh_core.c.

References BLI_mempool_free(), bm, BM_CHECK_ELEMENT, bm_kill_only_edge(), bm_kill_only_face(), bm_kill_only_loop(), bm_kill_only_vert(), bmesh_disk_edge_remove(), bmesh_radial_loop_remove(), BMVert::e, BMLoop::e, e, BMFace::l_first, BMLoop::next, NULL, v1, and v2.

Referenced by BM_mesh_intersect().

◆ BM_face_verts_kill()

void BM_face_verts_kill ( BMesh bm,
BMFace f 
)

kills all verts associated with f, along with any other faces containing those vertices

Definition at line 811 of file bmesh_core.c.

References BLI_array_alloca, bm, BM_FACE_FIRST_LOOP, BM_vert_kill(), BMFace::len, BMLoop::next, BMLoop::v, and verts.

Referenced by BM_edge_split(), and BM_face_split_n().

◆ BM_faces_join()

BMFace* BM_faces_join ( BMesh bm,
BMFace **  faces,
int  totface,
bool  do_del 
)

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.

Returns
The newly created combine BMFace.
Note
If a pair of faces share multiple edges, the pair of faces will be joined at every edge.
this is a generic, flexible join faces function, almost everything uses this, including BM_faces_join_pair

Definition at line 1123 of file bmesh_core.c.

References _FLAG_JF, BLI_addtail(), BLI_array_alloca, BLI_array_append, BLI_array_free, BLI_array_len, BLI_array_staticdeclare, BLI_assert, BLI_movelisttolist(), BLI_remlink(), bm, BM_CHECK_ELEMENT, BM_CREATE_NOP, BM_DEFAULT_NGON_STACK_SIZE, BM_edge_face_count_is_over, BM_edge_kill(), BM_edge_other_vert(), BM_ELEM_API_FLAG_DISABLE, BM_ELEM_API_FLAG_ENABLE, BM_ELEM_API_FLAG_TEST, BM_elem_attrs_copy(), bm_elements_systag_disable(), bm_elements_systag_enable(), BM_face_calc_center_median(), BM_face_create_ngon(), BM_FACE_FIRST_LOOP, BM_face_kill(), BM_loop_interp_multires_ex(), bm_loop_systag_count_radial(), bm_vert_is_manifold_flagged(), BM_vert_kill(), BMESH_ASSERT, CD_MDISPS, CustomData_get_offset(), BMLoop::e, error(), BMLoop::f, faces, float(), BMesh::ldata, BMLoop::next, NULL, BMLoop::radial_next, UNLIKELY, BMLoop::v, BMEdge::v1, v1, BMEdge::v2, and v2.

Referenced by bm_decim_triangulate_end(), bm_face_split_by_concave(), bm_face_split_by_edges_island_connect(), BM_faces_join_pair(), BM_vert_collapse_faces(), bmo_dissolve_faces_exec(), and bpy_bm_utils_face_join().

◆ bm_kill_only_edge()

static void bm_kill_only_edge ( BMesh bm,
BMEdge e 
)
static

◆ bm_kill_only_face()

static void bm_kill_only_face ( BMesh bm,
BMFace f 
)
static

◆ bm_kill_only_loop()

static void bm_kill_only_loop ( BMesh bm,
BMLoop l 
)
static

◆ bm_kill_only_vert()

static void bm_kill_only_vert ( BMesh bm,
BMVert v 
)
static

◆ bm_loop_create()

static BMLoop* bm_loop_create ( BMesh bm,
BMVert v,
BMEdge e,
BMFace f,
const BMLoop l_example,
const eBMCreateFlag  create_flag 
)
static

◆ bm_loop_length()

static int UNUSED_FUNCTION() bm_loop_length ( BMLoop l)
static

return the length of the face, should always equal l->f->len

Definition at line 953 of file bmesh_core.c.

References l, and BMLoop::next.

◆ bm_loop_systag_count_radial()

static int bm_loop_systag_count_radial ( BMLoop l,
const char  api_flag 
)
static

Definition at line 1061 of file bmesh_core.c.

References BM_ELEM_API_FLAG_TEST, BMLoop::f, l, and BMLoop::radial_next.

Referenced by BM_faces_join().

◆ BM_vert_create()

BMVert* BM_vert_create ( BMesh bm,
const float  co[3],
const BMVert v_example,
const eBMCreateFlag  create_flag 
)

Main function for creating a new vertex.

Definition at line 41 of file bmesh_core.c.

References BMHeader::api_flag, BLI_assert, BLI_mempool_alloc(), BLI_mempool_calloc(), bm, BM_CHECK_ELEMENT, BM_CREATE_NO_DOUBLE, BM_CREATE_SKIP_CD, BM_elem_attrs_copy(), BM_elem_index_set, BM_SPACEARR_DIRTY_ALL, BM_VERT, CD_SHAPE_KEYINDEX, BMVert::co, copy_v3_v3(), CustomData_bmesh_get(), CustomData_bmesh_set_default(), BMHeader::data, BMVert::e, BMesh::elem_index_dirty, BMesh::elem_table_dirty, BMVert::head, BMHeader::hflag, BMHeader::htype, BMVert::no, NULL, ORIGINDEX_NONE, BMesh::spacearr_dirty, BMesh::totvert, BMesh::use_toolflags, v, BMesh::vdata, BMesh::vpool, BMesh::vtoolflagpool, and zero_v3().

Referenced by BM_face_copy(), bm_face_split_edgenet_partial_connect(), bm_grid_fill_array(), bm_isect_edge_tri(), bm_log_verts_restore(), BM_mesh_bm_from_me(), BM_mesh_copy(), BM_mesh_wireframe(), bm_vert_copy(), bmesh_kernel_split_edge_make_vert(), bmesh_kernel_unglue_region_make_vert(), bmesh_kernel_unglue_region_make_vert_multi(), bmesh_kernel_unglue_region_make_vert_multi_isolated(), bmesh_kernel_vert_separate(), bmo_create_circle_exec(), bmo_create_cone_exec(), bmo_create_cube_exec(), bmo_create_grid_exec(), bmo_create_icosphere_exec(), bmo_create_monkey_exec(), bmo_create_uvsphere_exec(), bmo_create_vert_exec(), bmo_extrude_vert_indiv_exec(), bmo_face_inset_individual(), bmo_inset_region_exec(), bmo_poke_exec(), bmo_vert_copy(), bpy_bmvertseq_new(), create_mesh_bmvert(), edbm_polybuild_face_at_cursor_invoke(), knife_make_face_cuts(), output_frames(), pbvh_bmesh_vert_create(), skin_hole_detach_partially_attached_frame(), and TEST().

◆ bm_vert_is_manifold_flagged()

static bool bm_vert_is_manifold_flagged ( BMVert v,
const char  api_flag 
)
static

Return true when the vertex is manifold, attached to faces which are all flagged.

Definition at line 1092 of file bmesh_core.c.

References BM_edge_is_boundary(), BM_ELEM_API_FLAG_TEST, bmesh_disk_edge_next(), BMVert::e, BMLoop::e, e, BMLoop::f, l, BMLoop::radial_next, and v.

Referenced by BM_faces_join().

◆ BM_vert_kill()

void BM_vert_kill ( BMesh bm,
BMVert v 
)

◆ BM_vert_separate()

void BM_vert_separate ( BMesh bm,
BMVert v,
BMEdge **  e_in,
int  e_in_len,
bool  copy_select,
BMVert ***  r_vout,
int *  r_vout_len 
)

◆ BM_vert_separate_hflag()

void BM_vert_separate_hflag ( BMesh bm,
BMVert v,
char  hflag,
bool  copy_select,
BMVert ***  r_vout,
int *  r_vout_len 
)

◆ BM_vert_separate_tested_edges()

void BM_vert_separate_tested_edges ( BMesh UNUSEDbm,
BMVert v_dst,
BMVert v_src,
bool(*)(BMEdge *, void *arg)  testfn,
void arg 
)

◆ BM_vert_splice()

bool BM_vert_splice ( BMesh bm,
BMVert v_dst,
BMVert v_src 
)

Splice Vert.

Merges two verts into one (v_src into v_dst, removing v_src).

Returns
Success
Warning
This doesn't work for collapsing edges, where v and vtarget are connected by an edge (assert checks for this case).

Definition at line 2046 of file bmesh_core.c.

References BLI_assert, bm, BM_CHECK_ELEMENT, BM_vert_kill(), BM_vert_pair_share_face_check(), bmesh_edge_vert_swap(), BMVert::e, and e.

Referenced by bm_edge_collapse(), BM_face_split_edgenet_connect_islands(), BM_mesh_intersect(), bmo_inset_region_exec(), bmo_spin_exec(), bpy_bm_utils_vert_splice(), edbm_face_split_by_edges_exec(), and edbm_rip_invoke__vert().

◆ BM_vert_splice_check_double()

bool BM_vert_splice_check_double ( BMVert v_a,
BMVert v_b 
)

Check if splicing vertices would create any double edges.

Note
assume caller will handle case where verts share an edge.

Definition at line 2003 of file bmesh_core.c.

References BLI_assert, BM_DISK_EDGE_NEXT, BM_edge_exists(), BM_edge_other_vert(), BM_ELEM_API_FLAG_DISABLE, BM_ELEM_API_FLAG_ENABLE, BM_ELEM_API_FLAG_TEST, BMVert::e, e, and VERT_VISIT.

Referenced by BM_mesh_intersect().

◆ bm_vert_systag_count_disk()

static int UNUSED_FUNCTION() bm_vert_systag_count_disk ( BMVert v,
const char  api_flag 
)
static

Definition at line 1072 of file bmesh_core.c.

References BM_ELEM_API_FLAG_TEST, bmesh_disk_edge_next(), BMVert::e, e, and v.

◆ bmesh_edge_vert_swap__recursive()

static void bmesh_edge_vert_swap__recursive ( BMEdge e,
BMVert v_dst,
BMVert v_src 
)
static

◆ bmesh_elem_check()

int bmesh_elem_check ( void element,
char  htype 
)

◆ bmesh_face_swap_data()

void bmesh_face_swap_data ( BMFace f_a,
BMFace f_b 
)

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.

Definition at line 2651 of file bmesh_core.c.

References BLI_assert, BM_FACE_FIRST_LOOP, BMHeader::data, BMLoop::f, BMFace::head, BMHeader::index, BMLoop::next, and SWAP.

Referenced by BM_face_split_edgenet(), BM_face_triangulate(), and bmo_weld_verts_exec().

◆ bmesh_kernel_edge_separate()

void bmesh_kernel_edge_separate ( BMesh bm,
BMEdge e,
BMLoop l_sep,
bool  copy_select 
)

Separate Edge.

Separates a single edge into two edge: the original edge and a new edge that has only l_sep in its radial.

Returns
Success
Note
Does nothing if l_sep is already the only loop in the edge radial.

Definition at line 2365 of file bmesh_core.c.

References BLI_assert, bm, BM_CHECK_ELEMENT, BM_CREATE_NOP, BM_edge_create(), BM_edge_is_boundary(), BM_elem_select_copy(), bmesh_radial_length(), bmesh_radial_loop_append(), bmesh_radial_loop_remove(), BMLoop::e, e, BMEdge::l, and BMLoop::radial_next.

Referenced by BM_vert_separate(), BM_vert_separate_hflag(), bmesh_kernel_unglue_region_make_vert(), and bmo_inset_region_exec().

◆ bmesh_kernel_join_edge_kill_vert()

BMEdge* bmesh_kernel_join_edge_kill_vert ( BMesh bm,
BMEdge e_kill,
BMVert v_kill,
bool  do_del,
bool  check_edge_exists,
bool  kill_degenerate_faces,
bool  kill_duplicate_faces 
)

Join Edge Kill Vert (JEKV)

Takes an edge e_kill and pointer to one of its vertices v_kill and collapses the edge on that vertex.

Examples:
    Before:    e_old  e_kill
             +-------+-------+
             |       |       |
             v_old   v_kill  v_target

    After:           e_old
             +---------------+
             |               |
             v_old           v_target
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).
Returns
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.

Definition at line 1631 of file bmesh_core.c.

References BLI_assert, BLI_SMALLSTACK_DECLARE, BLI_SMALLSTACK_POP, BLI_SMALLSTACK_PUSH, bm, BM_CHECK_ELEMENT, BM_edge_exists(), BM_edge_other_vert(), BM_edge_splice(), BM_face_find_double(), BM_FACE_FIRST_LOOP, BM_face_kill(), bm_kill_only_edge(), bm_kill_only_loop(), bm_kill_only_vert(), BM_vert_in_edge(), BM_verts_in_edge(), BMESH_ASSERT, bmesh_disk_count(), bmesh_disk_count_at_most(), bmesh_disk_edge_next(), bmesh_disk_edge_remove(), bmesh_disk_validate(), bmesh_disk_vert_replace(), bmesh_loop_validate(), bmesh_radial_length(), bmesh_radial_validate(), BMVert::e, BMLoop::e, BMLoop::f, BMEdge::l, l, BMFace::len, BMLoop::next, NULL, BMLoop::prev, BMLoop::radial_next, and BMLoop::v.

Referenced by BM_vert_collapse_edge(), BM_vert_collapse_faces(), and bmo_offset_edgeloops_exec().

◆ bmesh_kernel_join_face_kill_edge()

BMFace* bmesh_kernel_join_face_kill_edge ( BMesh bm,
BMFace f1,
BMFace f2,
BMEdge e 
)

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

Examples:
          A                   B
     +--------+           +--------+
     |        |           |        |
     |   f1   |           |   f1   |
    v1========v2 = Ok!    v1==V2==v3 == Wrong!
     |   f2   |           |   f2   |
     |        |           |        |
     +--------+           +--------+

In the example A, faces f1 and f2 are joined by a single edge, and the euler can safely be used. In example B however, f1 and 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 f1 and 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 f1, not f2.
Returns
A BMFace pointer

Definition at line 1881 of file bmesh_core.c.

References BLI_mempool_free(), bm, BM_CHECK_ELEMENT, BM_EDGE, BM_edge_in_face(), BM_edge_is_manifold(), BM_elem_flag_disable, BM_elem_flag_set, BM_elem_flag_test, BM_ELEM_INTERNAL_TAG, BM_FACE, BM_face_edge_share_loop(), BM_FACE_FIRST_LOOP, BM_face_share_edge_count(), BM_LOOP, BMESH_ASSERT, bmesh_disk_edge_remove(), bmesh_loop_validate(), BMLoop::e, e, BMesh::elem_index_dirty, BMesh::epool, BMesh::etoolflagpool, BMLoop::f, BMesh::fpool, BMesh::ftoolflagpool, BMFace::len, BMesh::lpool, BMLoop::next, NULL, BMLoop::prev, BMesh::totedge, BMesh::totface, BMesh::totloop, BMLoop::v, BMEdge::v1, and BMEdge::v2.

Referenced by bmo_extrude_face_region_exec().

◆ bmesh_kernel_join_vert_kill_edge()

BMVert* bmesh_kernel_join_vert_kill_edge ( BMesh bm,
BMEdge e_kill,
BMVert v_kill,
bool  do_del,
bool  check_edge_exists,
bool  kill_degenerate_faces 
)

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.

Before: -> After:
+-+-+-+    +-+-+-+
| | | |    | \ / |
+-+-+-+    +--+--+
| | | |    | / \ |
+-+-+-+    +-+-+-+

Definition at line 1798 of file bmesh_core.c.

References BLI_assert, BLI_SMALLSTACK_DECLARE, BLI_SMALLSTACK_POP, BLI_SMALLSTACK_PUSH, bm, BM_CHECK_ELEMENT, BM_edge_exists(), BM_edge_kill(), BM_edge_other_vert(), BM_edge_splice(), BM_FACE_FIRST_LOOP, BM_face_kill(), bm_kill_only_loop(), bm_kill_only_vert(), BM_vert_in_edge(), bmesh_edge_vert_swap(), BMVert::e, e, BMLoop::f, BMEdge::l, BMFace::len, BMLoop::next, NULL, BMLoop::prev, BMLoop::radial_next, and BMLoop::v.

Referenced by BM_edge_collapse().

◆ bmesh_kernel_loop_reverse()

void bmesh_kernel_loop_reverse ( BMesh bm,
BMFace f,
int  cd_loop_mdisp_offset,
bool  use_loop_mdisp_flip 
)

Loop Reverse.

Changes the winding order of a face from CW to CCW or vice versa.

Parameters
cd_loop_mdisp_offsetCached result of CustomData_get_offset(&bm->ldata, CD_MDISPS).
use_loop_mdisp_flipWhen set, flip the Z-depth of the mdisp, (use when flipping normals, disable when mirroring, eg: symmetrize).

Definition at line 965 of file bmesh_core.c.

References BKE_mesh_mdisp_flip(), bm, BM_CHECK_ELEMENT, BM_ELEM_CD_GET_VOID_P, BM_LOOP, bmesh_radial_loop_append(), bmesh_radial_loop_remove(), BMLoop::e, BMesh::elem_index_dirty, BMLoop::f, BMEdge::l, BMFace::l_first, BMFace::len, BMLoop::next, BMLoop::prev, BMLoop::radial_next, BMLoop::radial_prev, SWAP, and BMLoop::v.

Referenced by BM_face_normal_flip_ex(), and BM_faces_join_pair().

◆ bmesh_kernel_split_edge_make_vert()

BMVert* bmesh_kernel_split_edge_make_vert ( BMesh bm,
BMVert tv,
BMEdge e,
BMEdge **  r_e 
)

Split Edge Make Vert (SEMV)

Takes e edge and splits it into two, creating a new vert. tv should be one end of e : the newly created edge will be attached to that end and is returned in r_e.

Examples:
                    E
    Before: OV-------------TV
                E       RE
    After:  OV------NV-----TV
Returns
The newly created BMVert pointer.

Definition at line 1478 of file bmesh_core.c.

References BLI_assert, bm, BM_CHECK_ELEMENT, BM_CREATE_NOP, BM_edge_create(), BM_edge_other_vert(), bm_loop_create(), BM_vert_create(), BM_vert_in_edge(), BM_verts_in_edge(), BMESH_ASSERT, bmesh_disk_count(), bmesh_disk_edge_append(), bmesh_disk_edge_remove(), bmesh_disk_validate(), bmesh_disk_vert_replace(), bmesh_radial_length(), bmesh_radial_loop_append(), bmesh_radial_loop_unlink(), bmesh_radial_validate(), BMVert::co, BMVert::e, BMLoop::e, e, BMLoop::f, BMEdge::l, l, BMFace::len, BMLoop::next, NULL, BMLoop::prev, BMLoop::radial_next, BMLoop::radial_prev, and BMLoop::v.

Referenced by BM_edge_split(), and BM_face_split_n().

◆ bmesh_kernel_split_face_make_edge()

BMFace* bmesh_kernel_split_face_make_edge ( BMesh bm,
BMFace f,
BMLoop l_v1,
BMLoop l_v2,
BMLoop **  r_l,
BMEdge example,
bool  no_double 
)

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.

Examples:
    Before:               After:
     +--------+           +--------+
     |        |           |        |
     |        |           |   f1   |
    v1   f1   v2          v1======v2
     |        |           |   f2   |
     |        |           |        |
     +--------+           +--------+
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.
If 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).
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.
Returns
A BMFace pointer

Definition at line 1339 of file bmesh_core.c.

References BLI_assert, BLI_mempool_free(), BLI_movelisttolist(), bm, BM_CHECK_ELEMENT, BM_CREATE_NO_DOUBLE, BM_CREATE_NOP, BM_edge_create(), bm_face_create__sfme(), BM_FACE_FIRST_LOOP, bm_loop_create(), bmesh_radial_loop_append(), e, BMLoop::f, BMFace::l_first, BMFace::len, BMLoop::next, NULL, BMLoop::prev, BMLoop::v, v1, and v2.

Referenced by BM_face_split(), and BM_face_split_n().

◆ bmesh_kernel_unglue_region_make_vert()

BMVert* bmesh_kernel_unglue_region_make_vert ( BMesh bm,
BMLoop l_sep 
)

Un-glue Region Make Vert (URMV)

Disconnects a face from its vertex fan at loop l_sep

Returns
The newly created BMVert
Note
Will be a no-op and return original vertex if only two edges at that vertex.

Definition at line 2400 of file bmesh_core.c.

References ARRAY_SIZE, BLI_assert, bm, BM_CHECK_ELEMENT, BM_CREATE_NOP, BM_edge_is_boundary(), BM_vert_create(), BM_vert_edge_count_is_equal, bmesh_disk_edge_next(), bmesh_edge_vert_swap(), bmesh_kernel_edge_separate(), BMVert::co, BMVert::e, BMLoop::e, e, ELEM, NULL, BMLoop::prev, and BMLoop::v.

Referenced by BM_face_loop_separate().

◆ bmesh_kernel_unglue_region_make_vert_multi()

BMVert* bmesh_kernel_unglue_region_make_vert_multi ( BMesh bm,
BMLoop **  larr,
int  larr_len 
)

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.

Definition at line 2462 of file bmesh_core.c.

References ARRAY_SIZE, BLI_array_alloca, BLI_assert, bm, BM_CREATE_NOP, BM_edge_create(), BM_ELEM_API_FLAG_DISABLE, BM_ELEM_API_FLAG_ENABLE, BM_ELEM_API_FLAG_TEST, BM_vert_create(), bmesh_disk_edge_next(), bmesh_disk_vert_replace(), bmesh_radial_loop_append(), bmesh_radial_loop_remove(), BMVert::co, BMVert::e, BMLoop::e, e, EDGE_VISIT, BMEdge::l, LOOP_VISIT, BMLoop::next, BMLoop::prev, BMLoop::radial_next, STACK_DECLARE, STACK_INIT, STACK_PUSH, STACK_SIZE, UNPACK2, and BMLoop::v.

Referenced by BM_face_loop_separate_multi().

◆ bmesh_kernel_unglue_region_make_vert_multi_isolated()

BMVert* bmesh_kernel_unglue_region_make_vert_multi_isolated ( BMesh bm,
BMLoop l_sep 
)

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.

Definition at line 2642 of file bmesh_core.c.

References BLI_assert, bm, BM_CREATE_NOP, BM_vert_create(), bmesh_edge_vert_swap__recursive(), BMVert::co, BMLoop::e, and BMLoop::v.

Referenced by BM_face_loop_separate_multi_isolated().

◆ bmesh_kernel_vert_separate()

void bmesh_kernel_vert_separate ( BMesh bm,
BMVert v,
BMVert ***  r_vout,
int *  r_vout_len,
bool  copy_select 
)

Separate Vert.

BMesh Kernel: For modifying structure.

Names are on the verbose side but these are only for low-level access.

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.
Returns
Success

Definition at line 2082 of file bmesh_core.c.

References BLI_assert, BLI_SMALLSTACK_AS_TABLE, BLI_SMALLSTACK_DECLARE, BLI_SMALLSTACK_POP, BLI_SMALLSTACK_PUSH, bm, BM_CREATE_NOP, BM_ELEM_API_FLAG_DISABLE, BM_ELEM_API_FLAG_ENABLE, BM_ELEM_API_FLAG_TEST, BM_elem_select_copy(), BM_vert_create(), BM_vert_in_edge(), bmesh_disk_edge_next(), bmesh_edge_vert_swap(), BMVert::co, BMVert::e, BMLoop::e, e, EDGE_VISIT, MEM_mallocN, BMLoop::next, NULL, BMLoop::prev, BMLoop::radial_next, BMLoop::v, v, and verts.

Referenced by BM_vert_separate(), BM_vert_separate_hflag(), bmo_inset_region_exec(), and edbm_rip_invoke__vert().

◆ bmesh_kernel_vert_separate__cleanup()

static void bmesh_kernel_vert_separate__cleanup ( BMesh bm,
LinkNode edges_separate 
)
static

Utility function for BM_vert_separate

Takes a list of edges, which have been split from their original.

Any edges which failed to split off in bmesh_kernel_vert_separate will be merged back into the original edge.

Parameters
edges_separateA list-of-lists, each list is from a single original edge (the first edge is the original), Check for duplicates (not just with the first) but between all. This is O(n2) but radial edges are very rarely >2 and almost never >~10.
Note
typically its best to avoid creating the data in the first place, but inspecting all loops connectivity is quite involved.
this function looks like it could become slow, but in common cases its only going to iterate a few times.

Definition at line 2210 of file bmesh_core.c.

References BLI_assert, bm, BM_edge_splice(), e, LinkNode::link, LinkNode::next, BMEdge::v1, and BMEdge::v2.

Referenced by BM_vert_separate(), and BM_vert_separate_hflag().