Blender  V2.93
Functions
bmesh_mesh_convert.c File Reference
#include "DNA_key_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
#include "MEM_guardedalloc.h"
#include "BLI_alloca.h"
#include "BLI_listbase.h"
#include "BLI_math_vector.h"
#include "BKE_customdata.h"
#include "BKE_mesh.h"
#include "BKE_mesh_runtime.h"
#include "BKE_multires.h"
#include "BKE_key.h"
#include "BKE_main.h"
#include "DEG_depsgraph_query.h"
#include "bmesh.h"
#include "intern/bmesh_private.h"

Go to the source code of this file.

Functions

void BM_mesh_cd_flag_ensure (BMesh *bm, Mesh *mesh, const char cd_flag)
 
void BM_mesh_cd_flag_apply (BMesh *bm, const char cd_flag)
 
char BM_mesh_cd_flag_from_bmesh (BMesh *bm)
 
static BMFacebm_face_create_from_mpoly (MPoly *mp, MLoop *ml, BMesh *bm, BMVert **vtable, BMEdge **etable)
 
void BM_mesh_bm_from_me (BMesh *bm, const Mesh *me, const struct BMeshFromMeshParams *params)
 Mesh -> BMesh. More...
 
static BMVert ** bm_to_mesh_vertex_map (BMesh *bm, int ototvert)
 BMesh -> Mesh. More...
 
static int bm_to_mesh_shape_layer_index_from_kb (BMesh *bm, KeyBlock *currkey)
 
BLI_INLINE void bmesh_quick_edgedraw_flag (MEdge *med, BMEdge *e)
 
void BM_mesh_bm_to_me (Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMeshParams *params)
 
void BM_mesh_bm_to_me_for_eval (BMesh *bm, Mesh *me, const CustomData_MeshMasks *cd_mask_extra)
 

Detailed Description

BM mesh conversion functions.

Converting Shape Keys

When converting to/from a Mesh/BMesh you can optionally pass a shape key to edit. This has the effect of editing the shape key-block rather than the original mesh vertex coords (although additional geometry is still allowed and uses fallback locations on converting).

While this works for any mesh/bmesh this is made use of by entering and exiting edit-mode.

There are comments in code but this should help explain the general intention as to how this works converting from/to bmesh.

User Perspective

Entering EditMode - #BM_mesh_bm_from_me

Exiting EditMode - #BM_mesh_bm_to_me

This is where the most confusing code is! Won't attempt to document the details here, for that read the code. But basics are as follows.

Copying the locations back to the shape keys is quite confusing... One main area of confusion is that when editing a 'Basis' key-block 'me->key->refkey' The coords are written into the mesh, from the users perspective the Basis coords are written into the mesh when exiting edit-mode.

When not editing the 'Basis', the original vertex locations (stored in the mesh and unchanged during edit-mode), are copied back into the mesh.

This has the effect from the users POV of leaving the mesh un-touched, and only editing the active shape key-block.

Definition in file bmesh_mesh_convert.c.

Function Documentation

◆ bm_face_create_from_mpoly()

static BMFace* bm_face_create_from_mpoly ( MPoly mp,
MLoop ml,
BMesh bm,
BMVert **  vtable,
BMEdge **  etable 
)
static

◆ BM_mesh_bm_from_me()

void BM_mesh_bm_from_me ( BMesh bm,
const Mesh me,
const struct BMeshFromMeshParams params 
)

Mesh -> BMesh.

Parameters
bmThe mesh to write into, while this is typically a newly created BMesh, merging into existing data is supported. Note the custom-data layout isn't used. If more comprehensive merging is needed we should move this into a separate function since this should be kept fast for edit-mode switching and storing undo steps.
Warning
This function doesn't calculate face normals.

Definition at line 189 of file bmesh_mesh_convert.c.

References BMesh::act_face, Mesh::act_face, BLI_array_alloca, BLI_assert, BLI_findlink(), BLI_listbase_count(), Key::block, bm, BM_CREATE_SKIP_CD, BM_EDGE, BM_edge_create(), BM_edge_flag_from_mflag(), BM_edge_select_set(), BM_ELEM_CD_GET_VOID_P, BM_ELEM_CD_SET_FLOAT, BM_ELEM_CD_SET_INT, BM_elem_index_set, BM_FACE, bm_face_create_from_mpoly(), BM_FACE_FIRST_LOOP, BM_face_flag_from_mflag(), BM_face_normal_update(), BM_face_select_set(), BM_LOOP, BM_mesh_cd_flag_apply(), BM_select_history_clear(), BM_select_history_store_notest, BM_VERT, BM_vert_create(), BM_vert_flag_from_mflag(), BM_vert_select_set(), MVert::bweight, MEdge::bweight, CD_ASSIGN, CD_BWEIGHT, CD_CALLOC, CD_CREASE, Mesh::cd_flag, CD_MASK_BMESH, CD_SHAPE_KEYINDEX, CD_SHAPEKEY, MVert::co, copy_v3_v3(), MEdge::crease, CustomData_add_layer(), CustomData_add_layer_named(), CustomData_bmesh_init_pool(), CustomData_bmesh_merge(), CustomData_copy(), CustomData_get_layer_index_n(), CustomData_get_offset(), CustomData_has_layer(), CustomData_MeshMasks_update(), CustomData_number_of_layers(), CustomData_to_bmesh_block(), BMHeader::data, KeyBlock::data, DEG_is_original_id(), e, BMesh::edata, BMesh::elem_index_dirty, ListBase::first, MVert::flag, MEdge::flag, MPoly::flag, float(), BMVert::head, BMLoop::head, BMFace::head, BMHeader::hflag, Mesh::id, MSelect::index, Mesh::key, CustomData::layers, BMesh::ldata, Mesh::ldata, MPoly::loopstart, mask(), BMFace::mat_nr, MPoly::mat_nr, ME_ESEL, ME_FACE_SEL, ME_FSEL, ME_VSEL, Mesh::medge, MEM_freeN, MEM_mallocN, min_ii(), Mesh::mloop, Mesh::mpoly, Mesh::mselect, Mesh::mvert, KeyBlock::name, ID::name, BMLoop::next, KeyBlock::next, next, BMVert::no, MVert::no, normal_short_to_float_v3(), NULL, params, BMesh::pdata, SELECT, BMesh::shapenr, Mesh::totedge, KeyBlock::totelem, BMesh::totface, CustomData::totlayer, Mesh::totloop, Mesh::totpoly, Mesh::totselect, BMesh::totvert, Mesh::totvert, MSelect::type, CustomDataLayer::uid, KeyBlock::uid, Key::uidgen, UNLIKELY, v, MEdge::v1, MEdge::v2, and BMesh::vdata.

Referenced by bc_triangulate_mesh(), BKE_mesh_remesh_voxel_fix_poles(), BKE_mesh_to_bmesh_ex(), BMD_mesh_bm_create(), bmo_mesh_to_bmesh_exec(), bpy_bmesh_from_mesh(), bpy_bmesh_from_object(), ED_uvedit_add_simple_uvs(), edbm_separate_exec(), geometry_extract_apply(), get_bmesh_from_mesh(), lineart_geometry_object_load(), paint_mask_slice_exec(), SCULPT_dynamic_topology_enable_ex(), sculpt_face_set_create_exec(), sculpt_face_set_delete_geometry(), sculpt_face_sets_init_flood_fill(), sculpt_face_sets_init_loop(), sculpt_gesture_apply_trim(), sculpt_gesture_trim_normals_update(), and undomesh_to_editmesh().

◆ BM_mesh_bm_to_me()

void BM_mesh_bm_to_me ( Main bmain,
BMesh bm,
Mesh me,
const struct BMeshToMeshParams params 
)
Parameters
bmainMay be NULL in case calc_object_remap parameter option is not set.

Definition at line 589 of file bmesh_mesh_convert.c.

References BMesh::act_face, Mesh::act_face, add_v3_v3(), BKE_keyblock_add(), BKE_keyblock_is_basis(), BKE_mesh_runtime_clear_geometry(), BKE_mesh_update_customdata_pointers(), BLI_assert, BLI_findlink(), BLI_listbase_count(), Key::block, bm, BM_CHECK_ELEMENT, BM_EDGE, BM_edge_flag_to_mflag(), BM_EDGES_OF_MESH, BM_ELEM_CD_GET_FLOAT_AS_UCHAR, BM_ELEM_CD_GET_INT, BM_ELEM_CD_GET_VOID_P, BM_ELEM_CD_SET_INT, BM_elem_index_get, BM_elem_index_set, BM_FACE, BM_FACE_FIRST_LOOP, BM_face_flag_to_mflag(), BM_FACES_OF_MESH, BM_ITER_MESH, BM_ITER_MESH_INDEX, BM_mesh_cd_flag_from_bmesh(), bm_to_mesh_shape_layer_index_from_kb(), bm_to_mesh_vertex_map(), BM_VERT, BM_vert_flag_to_mflag(), BM_VERTS_OF_MESH, bmesh_quick_edgedraw_flag(), MVert::bweight, MEdge::bweight, CD_ASSIGN, CD_BWEIGHT, CD_CALLOC, CD_CREASE, Mesh::cd_flag, CD_MASK_MESH, CD_MEDGE, CD_MLOOP, CD_MPOLY, CD_MVERT, CD_SHAPE_KEYINDEX, CD_SHAPEKEY, BMVert::co, MVert::co, copy_v3_v3(), MEdge::crease, CustomData_add_layer(), CustomData_copy(), CustomData_free(), CustomData_from_bmesh_block(), CustomData_get_n_offset(), CustomData_get_offset(), CustomData_MeshMasks_update(), CustomData_set_layer(), CustomData_update_typemap(), BMHeader::data, KeyBlock::data, Object::data, BMLoop::e, e, MLoop::e, BMesh::edata, BMEditSelection::ele, ELEM, BMesh::elem_index_dirty, Key::elemsize, eModifierType_Hook, Mesh::fdata, ListBase::first, MVert::flag, MEdge::flag, MPoly::flag, float(), BMVert::head, BMLoop::head, BMFace::head, BMEditSelection::htype, Object::id, MSelect::index, HookModifierData::indexar, Mesh::key, KEY_RELATIVE, CustomData::layers, BMesh::ldata, Mesh::ldata, BMFace::len, MPoly::loopstart, mask(), BMFace::mat_nr, MPoly::mat_nr, ME_ESEL, ME_FSEL, ME_VSEL, MEM_callocN, MEM_dupallocN, MEM_freeN, MEM_mallocN, MEM_SAFE_FREE, Object::modifiers, Mesh::mselect, multires_topology_changed(), Mesh::mvert, CustomDataLayer::name, BMLoop::next, BMEditSelection::next, ID::next, KeyBlock::next, ModifierData::next, BMVert::no, MVert::no, normal_float_to_short_v3(), NULL, Main::objects, ORIGINDEX_NONE, Object::par1, Object::par2, Object::par3, params, Object::parent, Object::partype, PARVERT1, PARVERT3, BMesh::pdata, Key::refkey, KeyBlock::relative, BMesh::selected, BMesh::shapenr, sub_v3_v3v3(), BMesh::totedge, Mesh::totedge, KeyBlock::totelem, BMesh::totface, Mesh::totface, HookModifierData::totindex, CustomData::totlayer, BMesh::totloop, Mesh::totloop, MPoly::totloop, Mesh::totpoly, Mesh::totselect, BMesh::totvert, Mesh::totvert, CustomDataLayer::type, Key::type, MSelect::type, ModifierData::type, CustomDataLayer::uid, KeyBlock::uid, BMLoop::v, v, MLoop::v, MEdge::v1, MEdge::v2, and BMesh::vdata.

Referenced by bc_triangulate_mesh(), BKE_mesh_from_bmesh_nomain(), BKE_mesh_mirror_apply_mirror_on_axis(), bmo_bmesh_to_mesh_exec(), bpy_bmesh_to_mesh(), blender::nodes::create_cube_mesh(), blender::nodes::create_ico_sphere_mesh(), ED_uvedit_add_simple_uvs(), EDBM_mesh_load_ex(), edbm_separate_exec(), mesh_separate_arrays(), mesh_separate_loose(), mesh_separate_tagged(), modifyMesh(), multires_unsubdivide_to_basemesh(), prepare_mesh_for_viewport_render(), sculpt_face_set_delete_geometry(), sculptsession_bm_to_me_update_data_only(), and undomesh_from_editmesh().

◆ BM_mesh_bm_to_me_for_eval()

void BM_mesh_bm_to_me_for_eval ( BMesh bm,
Mesh me,
const CustomData_MeshMasks cd_mask_extra 
)

A version of BM_mesh_bm_to_me intended for getting the mesh to pass to the modifier stack for evaluation, instead of mode switching (where we make sure all data is kept and do expensive lookups to maintain shape keys).

Key differences:

Note
Was cddm_from_bmesh_ex in 2.7x, removed MFace support.

Definition at line 1025 of file bmesh_mesh_convert.c.

References BKE_mesh_update_customdata_pointers(), BLI_assert, bm, BM_EDGE, BM_edge_flag_to_mflag(), BM_EDGES_OF_MESH, BM_ELEM_CD_GET_FLOAT_AS_UCHAR, BM_elem_index_get, BM_elem_index_set, BM_FACE, BM_FACE_FIRST_LOOP, BM_face_flag_to_mflag(), BM_FACES_OF_MESH, BM_ITER_MESH_INDEX, BM_LOOP, BM_mesh_cd_flag_from_bmesh(), BM_VERT, BM_vert_flag_to_mflag(), BM_VERTS_OF_MESH, MEdge::bweight, CD_BWEIGHT, CD_CALLOC, CD_CREASE, Mesh::cd_flag, CD_MASK_DERIVEDMESH, CD_MASK_SHAPEKEY, CD_MEDGE, CD_MLOOP, CD_MPOLY, CD_MVERT, CD_ORIGINDEX, BMVert::co, copy_v3_v3(), MEdge::crease, CustomData_add_layer(), CustomData_from_bmesh_block(), CustomData_get_layer(), CustomData_get_offset(), CustomData_has_layer(), CustomData_merge(), CustomData_MeshMasks_update(), BMHeader::data, Mesh_Runtime::deformed_only, BMLoop::e, MLoop::e, BMesh::edata, BMesh::elem_index_dirty, MEdge::flag, MPoly::flag, BMVert::head, BMEdge::head, BMLoop::head, BMFace::head, BMEdge::l, BMesh::ldata, Mesh::ldata, BMFace::len, MPoly::loopstart, mask(), BMFace::mat_nr, MPoly::mat_nr, ME_EDGEDRAW, Mesh::medge, Mesh::mloop, Mesh::mpoly, Mesh::mvert, BMLoop::next, BMVert::no, normal_float_to_short_v3(), NULL, BMesh::pdata, BMLoop::radial_next, Mesh::runtime, BMesh::totedge, Mesh::totedge, BMesh::totface, Mesh::totface, BMesh::totloop, Mesh::totloop, MPoly::totloop, Mesh::totpoly, BMesh::totvert, Mesh::totvert, BMLoop::v, MLoop::v, BMEdge::v1, MEdge::v1, BMEdge::v2, MEdge::v2, BMesh::vdata, and CustomData_MeshMasks::vmask.

Referenced by BKE_mesh_from_bmesh_for_eval_nomain(), BKE_mesh_wrapper_ensure_mdata(), and blender::ed::spreadsheet::get_display_geometry_set().

◆ BM_mesh_cd_flag_apply()

void BM_mesh_cd_flag_apply ( BMesh bm,
const char  cd_flag 
)

◆ BM_mesh_cd_flag_ensure()

void BM_mesh_cd_flag_ensure ( BMesh bm,
Mesh mesh,
const char  cd_flag 
)

◆ BM_mesh_cd_flag_from_bmesh()

char BM_mesh_cd_flag_from_bmesh ( BMesh bm)

◆ bm_to_mesh_shape_layer_index_from_kb()

static int bm_to_mesh_shape_layer_index_from_kb ( BMesh bm,
KeyBlock currkey 
)
static

Returns custom-data shapekey index from a keyblock or -1

Note
could split this out into a more generic function.

Definition at line 552 of file bmesh_mesh_convert.c.

References bm, CD_SHAPEKEY, CustomData::layers, CustomData::totlayer, CustomDataLayer::type, CustomDataLayer::uid, KeyBlock::uid, and BMesh::vdata.

Referenced by BM_mesh_bm_to_me().

◆ bm_to_mesh_vertex_map()

static BMVert** bm_to_mesh_vertex_map ( BMesh bm,
int  ototvert 
)
static

◆ bmesh_quick_edgedraw_flag()

BLI_INLINE void bmesh_quick_edgedraw_flag ( MEdge med,
BMEdge e 
)

Definition at line 568 of file bmesh_mesh_convert.c.

References dot_v3v3(), e, MEdge::flag, ME_EDGEDRAW, and BMVert::no.

Referenced by BM_mesh_bm_to_me().