Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/editmesh.c
| Show All 30 Lines | |||||
| #include "BLI_math.h" | #include "BLI_math.h" | ||||
| #include "BKE_DerivedMesh.h" | #include "BKE_DerivedMesh.h" | ||||
| #include "BKE_editmesh.h" | #include "BKE_editmesh.h" | ||||
| #include "BKE_editmesh_cache.h" | #include "BKE_editmesh_cache.h" | ||||
| #include "BKE_lib_id.h" | #include "BKE_lib_id.h" | ||||
| #include "BKE_mesh.h" | #include "BKE_mesh.h" | ||||
| #include "BKE_mesh_iterators.h" | #include "BKE_mesh_iterators.h" | ||||
| #include "BKE_mesh_runtime.h" | |||||
| #include "BKE_mesh_wrapper.h" | #include "BKE_mesh_wrapper.h" | ||||
| #include "BKE_object.h" | #include "BKE_object.h" | ||||
| BMEditMesh *BKE_editmesh_create(BMesh *bm, const bool do_tessellate) | BMEditMesh *BKE_editmesh_create(BMesh *bm, const bool do_tessellate) | ||||
| { | { | ||||
| BMEditMesh *em = MEM_callocN(sizeof(BMEditMesh), __func__); | BMEditMesh *em = MEM_callocN(sizeof(BMEditMesh), __func__); | ||||
| em->bm = bm; | em->bm = bm; | ||||
| if (do_tessellate) { | if (do_tessellate) { | ||||
| BKE_editmesh_looptri_calc(em); | BKE_editmesh_looptri_calc(em); | ||||
| } | } | ||||
| return em; | return em; | ||||
| } | } | ||||
| BMEditMesh *BKE_editmesh_copy(BMEditMesh *em) | BMEditMesh *BKE_editmesh_copy(BMEditMesh *em) | ||||
| { | { | ||||
| BMEditMesh *em_copy = MEM_callocN(sizeof(BMEditMesh), __func__); | BMEditMesh *em_copy = MEM_callocN(sizeof(BMEditMesh), __func__); | ||||
| *em_copy = *em; | *em_copy = *em; | ||||
| em_copy->mesh_eval_cage = em_copy->mesh_eval_final = NULL; | |||||
| em_copy->bb_cage = NULL; | |||||
| em_copy->bm = BM_mesh_copy(em->bm); | em_copy->bm = BM_mesh_copy(em->bm); | ||||
| /* The tessellation is NOT calculated on the copy here, | /* The tessellation is NOT calculated on the copy here, | ||||
| * because currently all the callers of this function use | * because currently all the callers of this function use | ||||
| * it to make a backup copy of the #BMEditMesh to restore | * it to make a backup copy of the #BMEditMesh to restore | ||||
| * it in the case of errors in an operation. For performance reasons, | * it in the case of errors in an operation. For performance reasons, | ||||
| * in that case it makes more sense to do the | * in that case it makes more sense to do the | ||||
| * tessellation only when/if that copy ends up getting used. */ | * tessellation only when/if that copy ends up getting used. */ | ||||
| ▲ Show 20 Lines • Show All 73 Lines • ▼ Show 20 Lines | #if 0 | ||||
| } | } | ||||
| else if (em->mesh_eval_final) { | else if (em->mesh_eval_final) { | ||||
| BKE_mesh_runtime_looptri_ensure(em->mesh_eval_final); | BKE_mesh_runtime_looptri_ensure(em->mesh_eval_final); | ||||
| BKE_mesh_runtime_looptri_ensure(em->mesh_eval_cage); | BKE_mesh_runtime_looptri_ensure(em->mesh_eval_cage); | ||||
| } | } | ||||
| #endif | #endif | ||||
| } | } | ||||
| void BKE_editmesh_free_derivedmesh(BMEditMesh *em) | void BKE_editmesh_free_derivedmesh(Mesh *me, BMEditMesh *em) | ||||
| { | { | ||||
| if (em->mesh_eval_cage) { | UNUSED_VARS(em); | ||||
| BKE_id_free(NULL, em->mesh_eval_cage); | EditMeshData *emd = me->runtime.edit_data; | ||||
| if (emd == NULL) { | |||||
| return; | |||||
| } | |||||
| /* All have been moved to #EditMeshData. */ | |||||
| if (emd->eval.mesh_eval_cage) { | |||||
| BKE_id_free(NULL, emd->eval.mesh_eval_cage); | |||||
| } | } | ||||
| if (em->mesh_eval_final && em->mesh_eval_final != em->mesh_eval_cage) { | if (emd->eval.mesh_eval_final && emd->eval.mesh_eval_final != emd->eval.mesh_eval_cage) { | ||||
| BKE_id_free(NULL, em->mesh_eval_final); | BKE_id_free(NULL, emd->eval.mesh_eval_final); | ||||
| } | } | ||||
| em->mesh_eval_cage = em->mesh_eval_final = NULL; | emd->eval.mesh_eval_cage = emd->eval.mesh_eval_final = NULL; | ||||
| MEM_SAFE_FREE(em->bb_cage); | MEM_SAFE_FREE(emd->eval.bb_cage); | ||||
| } | } | ||||
| /*does not free the BMEditMesh struct itself*/ | /*does not free the BMEditMesh struct itself*/ | ||||
| void BKE_editmesh_free(BMEditMesh *em) | void BKE_editmesh_free(BMEditMesh *em) | ||||
| { | { | ||||
| BKE_editmesh_free_derivedmesh(em); | |||||
| if (em->looptris) { | if (em->looptris) { | ||||
| MEM_freeN(em->looptris); | MEM_freeN(em->looptris); | ||||
| } | } | ||||
| if (em->bm) { | if (em->bm) { | ||||
| BM_mesh_free(em->bm); | BM_mesh_free(em->bm); | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | const float (*BKE_editmesh_vert_coords_when_deformed(struct Depsgraph *depsgraph, | ||||
| Object *ob, | Object *ob, | ||||
| int *r_vert_len, | int *r_vert_len, | ||||
| bool *r_is_alloc))[3] | bool *r_is_alloc))[3] | ||||
| { | { | ||||
| const float(*coords)[3] = NULL; | const float(*coords)[3] = NULL; | ||||
| *r_is_alloc = false; | *r_is_alloc = false; | ||||
| Mesh *me = ob->data; | Mesh *me = ob->data; | ||||
| EditMeshData *emd = me->runtime.edit_data; | |||||
| if ((me->runtime.edit_data != NULL) && (me->runtime.edit_data->vertexCos != NULL)) { | if ((emd != NULL) && (emd->vertexCos != NULL)) { | ||||
| /* Deformed, and we have deformed coords already. */ | /* Deformed, and we have deformed coords already. */ | ||||
| coords = me->runtime.edit_data->vertexCos; | coords = emd->vertexCos; | ||||
| } | } | ||||
| else if ((em->mesh_eval_final != NULL) && | else if ((emd != NULL) && (emd->eval.mesh_eval_final != NULL) && | ||||
| (em->mesh_eval_final->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH)) { | (emd->eval.mesh_eval_final->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH)) { | ||||
| /* If this is an edit-mesh type, leave NULL as we can use the vertex coords. . */ | /* If this is an edit-mesh type, leave NULL as we can use the vertex coords. . */ | ||||
| } | } | ||||
| else { | else { | ||||
| /* Constructive modifiers have been used, we need to allocate coordinates. */ | /* Constructive modifiers have been used, we need to allocate coordinates. */ | ||||
| *r_is_alloc = true; | *r_is_alloc = true; | ||||
| coords = BKE_editmesh_vert_coords_alloc(depsgraph, em, scene, ob, r_vert_len); | coords = BKE_editmesh_vert_coords_alloc(depsgraph, em, scene, ob, r_vert_len); | ||||
| } | } | ||||
| return coords; | return coords; | ||||
| Show All 29 Lines | |||||
| void BKE_editmesh_ensure_autosmooth(BMEditMesh *em, Mesh *me) | void BKE_editmesh_ensure_autosmooth(BMEditMesh *em, Mesh *me) | ||||
| { | { | ||||
| if (!(me->flag & ME_AUTOSMOOTH)) { | if (!(me->flag & ME_AUTOSMOOTH)) { | ||||
| me->flag |= ME_AUTOSMOOTH; | me->flag |= ME_AUTOSMOOTH; | ||||
| BKE_editmesh_lnorspace_update(em, me); | BKE_editmesh_lnorspace_update(em, me); | ||||
| } | } | ||||
| } | } | ||||
| BoundBox *BKE_editmesh_cage_boundbox_get(BMEditMesh *em) | BoundBox *BKE_editmesh_cage_boundbox_get(Object *obedit, BMEditMesh *em) | ||||
| { | { | ||||
| if (em->bb_cage == NULL) { | Mesh *me = obedit->data; | ||||
| BKE_mesh_runtime_ensure_edit_data(me); | |||||
| EditMeshData *edit_data = me->runtime.edit_data; | |||||
| if (edit_data->eval.bb_cage == NULL) { | |||||
| float min[3], max[3]; | float min[3], max[3]; | ||||
| INIT_MINMAX(min, max); | INIT_MINMAX(min, max); | ||||
| if (em->mesh_eval_cage) { | if (edit_data->eval.mesh_eval_cage) { | ||||
| BKE_mesh_wrapper_minmax(em->mesh_eval_cage, min, max); | BKE_mesh_wrapper_minmax(edit_data->eval.mesh_eval_cage, min, max); | ||||
| } | } | ||||
| em->bb_cage = MEM_callocN(sizeof(BoundBox), "BMEditMesh.bb_cage"); | edit_data->eval.bb_cage = MEM_callocN(sizeof(BoundBox), "BMEditMesh.bb_cage"); | ||||
| BKE_boundbox_init_from_minmax(em->bb_cage, min, max); | BKE_boundbox_init_from_minmax(edit_data->eval.bb_cage, min, max); | ||||
| } | } | ||||
| return em->bb_cage; | return edit_data->eval.bb_cage; | ||||
| } | } | ||||