Cleanup: Use C++ Array types for Edit Mesh SoA cache

This helps const correctness since the data can't be changed from a
const EditMeshData struct, and simplifies memory management.

Pull Request: https://projects.blender.org/blender/blender/pulls/109821
This commit is contained in:
Hans Goudey 2023-07-10 19:49:54 +02:00 committed by Hans Goudey
parent 94914d12f3
commit 3d383d383f
16 changed files with 163 additions and 194 deletions

View File

@ -246,7 +246,6 @@ struct Mesh *editbmesh_get_eval_cage_from_orig(struct Depsgraph *depsgraph,
struct Object *obedit,
const struct CustomData_MeshMasks *dataMask);
float (*editbmesh_vert_coords_alloc(struct BMEditMesh *em))[3];
bool editbmesh_modifier_is_enabled(const struct Scene *scene,
const struct Object *ob,
struct ModifierData *md,

View File

@ -8,22 +8,32 @@
* \ingroup bke
*/
#include "BLI_array.hh"
#include "BLI_math_vector_types.hh"
struct BMEditMesh;
namespace blender::bke {
struct EditMeshData {
/** when set, \a vertexNos, polyNos are lazy initialized */
float (*vertexCos)[3];
Array<float3> vertexCos;
/** lazy initialize (when \a vertexCos is set) */
float const (*vertexNos)[3];
float const (*polyNos)[3];
Array<float3> vertexNos;
Array<float3> polyNos;
/** also lazy init but don't depend on \a vertexCos */
const float (*polyCos)[3];
Array<float3> polyCos;
};
void BKE_editmesh_cache_ensure_poly_normals(BMEditMesh *em, EditMeshData *emd);
void BKE_editmesh_cache_ensure_vert_normals(BMEditMesh *em, EditMeshData *emd);
} // namespace blender::bke
void BKE_editmesh_cache_ensure_poly_centers(BMEditMesh *em, EditMeshData *emd);
void BKE_editmesh_cache_ensure_poly_normals(BMEditMesh *em, blender::bke::EditMeshData *emd);
void BKE_editmesh_cache_ensure_vert_normals(BMEditMesh *em, blender::bke::EditMeshData *emd);
bool BKE_editmesh_cache_calc_minmax(BMEditMesh *em, EditMeshData *emd, float min[3], float max[3]);
void BKE_editmesh_cache_ensure_poly_centers(BMEditMesh *em, blender::bke::EditMeshData *emd);
bool BKE_editmesh_cache_calc_minmax(BMEditMesh *em,
blender::bke::EditMeshData *emd,
float min[3],
float max[3]);

View File

@ -23,12 +23,14 @@
# include "DNA_meshdata_types.h"
struct BVHCache;
struct EditMeshData;
struct Mesh;
struct MLoopTri;
struct ShrinkwrapBoundaryData;
struct SubdivCCG;
struct SubsurfRuntimeData;
namespace blender::bke {
struct EditMeshData;
}
#endif

View File

@ -1051,19 +1051,15 @@ static void mesh_calc_modifiers(Depsgraph *depsgraph,
}
}
float (*editbmesh_vert_coords_alloc(BMEditMesh *em))[3]
static blender::Array<float3> editbmesh_vert_coords_alloc(const BMEditMesh *em)
{
blender::Array<float3> cos(em->bm->totvert);
BMIter iter;
BMVert *eve;
float(*cos)[3];
int i;
cos = (float(*)[3])MEM_malloc_arrayN(em->bm->totvert, sizeof(float[3]), "vertexcos");
BM_ITER_MESH_INDEX (eve, &iter, em->bm, BM_VERTS_OF_MESH, i) {
copy_v3_v3(cos[i], eve->co);
cos[i] = eve->co;
}
return cos;
}
@ -1131,19 +1127,20 @@ static void editbmesh_calc_modifier_final_normals_or_defer(
editbmesh_calc_modifier_final_normals(mesh_final, final_datamask);
}
static float (*mesh_wrapper_vert_coords_ensure_for_write(Mesh *mesh))[3]
static blender::MutableSpan<float3> mesh_wrapper_vert_coords_ensure_for_write(Mesh *mesh)
{
switch (mesh->runtime->wrapper_type) {
case ME_WRAPPER_TYPE_BMESH:
if (mesh->runtime->edit_data->vertexCos == nullptr) {
if (mesh->runtime->edit_data->vertexCos.is_empty()) {
mesh->runtime->edit_data->vertexCos = editbmesh_vert_coords_alloc(mesh->edit_mesh);
}
return mesh->runtime->edit_data->vertexCos;
case ME_WRAPPER_TYPE_MDATA:
case ME_WRAPPER_TYPE_SUBD:
return reinterpret_cast<float(*)[3]>(mesh->vert_positions_for_write().data());
return mesh->vert_positions_for_write();
}
return nullptr;
BLI_assert_unreachable();
return {};
}
static void editbmesh_calc_modifiers(Depsgraph *depsgraph,
@ -1244,12 +1241,14 @@ static void editbmesh_calc_modifiers(Depsgraph *depsgraph,
if (mti->type == eModifierTypeType_OnlyDeform) {
if (mti->deformVertsEM) {
BKE_modifier_deform_vertsEM(md,
&mectx,
em_input,
mesh_final,
mesh_wrapper_vert_coords_ensure_for_write(mesh_final),
BKE_mesh_wrapper_vert_len(mesh_final));
BKE_modifier_deform_vertsEM(
md,
&mectx,
em_input,
mesh_final,
reinterpret_cast<float(*)[3]>(
mesh_wrapper_vert_coords_ensure_for_write(mesh_final).data()),
BKE_mesh_wrapper_vert_len(mesh_final));
BKE_mesh_wrapper_tag_positions_changed(mesh_final);
}
else {

View File

@ -278,7 +278,9 @@ int BKE_crazyspace_get_first_deform_matrices_editbmesh(Depsgraph *depsgraph,
BLI_linklist_free((LinkNode *)datamasks, nullptr);
me = BKE_mesh_wrapper_from_editmesh(em, &cd_mask_extra, me_input);
deformedVerts = editbmesh_vert_coords_alloc(em);
deformedVerts = static_cast<float(*)[3]>(
MEM_mallocN(sizeof(*deformedVerts) * verts_num, __func__));
BKE_mesh_wrapper_vert_coords_copy(me, deformedVerts, verts_num);
defmats = static_cast<float(*)[3][3]>(
MEM_mallocN(sizeof(*defmats) * verts_num, "defmats"));

View File

@ -23,88 +23,70 @@
/** \name Ensure Data (derived from coords)
* \{ */
void BKE_editmesh_cache_ensure_poly_normals(BMEditMesh *em, EditMeshData *emd)
void BKE_editmesh_cache_ensure_poly_normals(BMEditMesh *em, blender::bke::EditMeshData *emd)
{
if (!(emd->vertexCos && (emd->polyNos == nullptr))) {
if (emd->vertexCos.is_empty() || !emd->polyNos.is_empty()) {
return;
}
BMesh *bm = em->bm;
emd->polyNos.reinitialize(bm->totface);
BM_mesh_elem_index_ensure(bm, BM_VERT);
BMFace *efa;
BMIter fiter;
int i;
BM_mesh_elem_index_ensure(bm, BM_VERT);
float(*polyNos)[3] = static_cast<float(*)[3]>(
MEM_mallocN(sizeof(*polyNos) * bm->totface, __func__));
const float(*vertexCos)[3] = emd->vertexCos;
BM_ITER_MESH_INDEX (efa, &fiter, bm, BM_FACES_OF_MESH, i) {
BM_elem_index_set(efa, i); /* set_inline */
BM_face_calc_normal_vcos(bm, efa, polyNos[i], vertexCos);
BM_face_calc_normal_vcos(
bm, efa, emd->polyNos[i], reinterpret_cast<const float(*)[3]>(emd->vertexCos.data()));
}
bm->elem_index_dirty &= ~BM_FACE;
emd->polyNos = (const float(*)[3])polyNos;
}
void BKE_editmesh_cache_ensure_vert_normals(BMEditMesh *em, EditMeshData *emd)
void BKE_editmesh_cache_ensure_vert_normals(BMEditMesh *em, blender::bke::EditMeshData *emd)
{
if (!(emd->vertexCos && (emd->vertexNos == nullptr))) {
if (emd->vertexCos.is_empty() || !emd->vertexNos.is_empty()) {
return;
}
BMesh *bm = em->bm;
const float(*vertexCos)[3], (*polyNos)[3];
float(*vertexNos)[3];
/* Calculate vertex normals from poly normals. */
BKE_editmesh_cache_ensure_poly_normals(em, emd);
emd->vertexNos.reinitialize(bm->totvert);
BM_mesh_elem_index_ensure(bm, BM_FACE);
polyNos = emd->polyNos;
vertexCos = emd->vertexCos;
vertexNos = static_cast<float(*)[3]>(MEM_callocN(sizeof(*vertexNos) * bm->totvert, __func__));
BM_verts_calc_normal_vcos(bm, polyNos, vertexCos, vertexNos);
emd->vertexNos = (const float(*)[3])vertexNos;
BM_verts_calc_normal_vcos(bm,
reinterpret_cast<const float(*)[3]>(emd->polyNos.data()),
reinterpret_cast<const float(*)[3]>(emd->vertexCos.data()),
reinterpret_cast<float(*)[3]>(emd->vertexNos.data()));
}
void BKE_editmesh_cache_ensure_poly_centers(BMEditMesh *em, EditMeshData *emd)
void BKE_editmesh_cache_ensure_poly_centers(BMEditMesh *em, blender::bke::EditMeshData *emd)
{
if (emd->polyCos != nullptr) {
if (!emd->polyCos.is_empty()) {
return;
}
BMesh *bm = em->bm;
emd->polyCos.reinitialize(bm->totface);
BMFace *efa;
BMIter fiter;
int i;
float(*polyCos)[3] = static_cast<float(*)[3]>(
MEM_mallocN(sizeof(*polyCos) * bm->totface, __func__));
if (emd->vertexCos) {
const float(*vertexCos)[3];
vertexCos = emd->vertexCos;
BM_mesh_elem_index_ensure(bm, BM_VERT);
if (emd->vertexCos.is_empty()) {
BM_ITER_MESH_INDEX (efa, &fiter, bm, BM_FACES_OF_MESH, i) {
BM_face_calc_center_median_vcos(bm, efa, polyCos[i], vertexCos);
BM_face_calc_center_median(efa, emd->polyCos[i]);
}
}
else {
BM_mesh_elem_index_ensure(bm, BM_VERT);
BM_ITER_MESH_INDEX (efa, &fiter, bm, BM_FACES_OF_MESH, i) {
BM_face_calc_center_median(efa, polyCos[i]);
BM_face_calc_center_median_vcos(
bm, efa, emd->polyCos[i], reinterpret_cast<const float(*)[3]>(emd->vertexCos.data()));
}
}
emd->polyCos = (const float(*)[3])polyCos;
}
/** \} */
@ -113,32 +95,32 @@ void BKE_editmesh_cache_ensure_poly_centers(BMEditMesh *em, EditMeshData *emd)
/** \name Calculate Min/Max
* \{ */
bool BKE_editmesh_cache_calc_minmax(BMEditMesh *em, EditMeshData *emd, float min[3], float max[3])
bool BKE_editmesh_cache_calc_minmax(BMEditMesh *em,
blender::bke::EditMeshData *emd,
float min[3],
float max[3])
{
using namespace blender;
BMesh *bm = em->bm;
if (bm->totvert) {
if (emd->vertexCos) {
Span<float3> vert_coords(reinterpret_cast<const float3 *>(emd->vertexCos), bm->totvert);
std::optional<Bounds<float3>> bounds = bounds::min_max(vert_coords);
BLI_assert(bounds.has_value());
copy_v3_v3(min, math::min(bounds->min, float3(min)));
copy_v3_v3(max, math::max(bounds->max, float3(max)));
}
else {
BMVert *eve;
BMIter iter;
BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
minmax_v3v3_v3(min, max, eve->co);
}
}
return true;
if (bm->totvert == 0) {
zero_v3(min);
zero_v3(max);
return false;
}
zero_v3(min);
zero_v3(max);
return false;
if (emd->vertexCos.is_empty()) {
BMVert *eve;
BMIter iter;
BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
minmax_v3v3_v3(min, max, eve->co);
}
}
else {
const Bounds<float3> bounds = *bounds::min_max(emd->vertexCos.as_span());
copy_v3_v3(min, math::min(bounds.min, float3(min)));
copy_v3_v3(max, math::max(bounds.max, float3(max)));
}
return true;
}
/** \} */

View File

@ -44,19 +44,16 @@ void BKE_mesh_foreach_mapped_vert(
BMIter iter;
BMVert *eve;
int i;
if (mesh->runtime->edit_data->vertexCos != nullptr) {
const float(*vertexCos)[3] = mesh->runtime->edit_data->vertexCos;
const float(*vertexNos)[3];
if (!mesh->runtime->edit_data->vertexCos.is_empty()) {
const blender::Span<blender::float3> positions = mesh->runtime->edit_data->vertexCos;
blender::Span<blender::float3> vert_normals;
if (flag & MESH_FOREACH_USE_NORMAL) {
BKE_editmesh_cache_ensure_vert_normals(em, mesh->runtime->edit_data);
vertexNos = mesh->runtime->edit_data->vertexNos;
}
else {
vertexNos = nullptr;
vert_normals = mesh->runtime->edit_data->vertexNos;
}
BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
const float *no = (flag & MESH_FOREACH_USE_NORMAL) ? vertexNos[i] : nullptr;
func(userData, i, vertexCos[i], no);
const float *no = (flag & MESH_FOREACH_USE_NORMAL) ? &vert_normals[i].x : nullptr;
func(userData, i, positions[i], no);
}
}
else {
@ -105,15 +102,14 @@ void BKE_mesh_foreach_mapped_edge(
BMIter iter;
BMEdge *eed;
int i;
if (mesh->runtime->edit_data->vertexCos != nullptr) {
const float(*vertexCos)[3] = mesh->runtime->edit_data->vertexCos;
if (!mesh->runtime->edit_data->vertexCos.is_empty()) {
const blender::Span<blender::float3> positions = mesh->runtime->edit_data->vertexCos;
BM_mesh_elem_index_ensure(bm, BM_VERT);
BM_ITER_MESH_INDEX (eed, &iter, bm, BM_EDGES_OF_MESH, i) {
func(userData,
i,
vertexCos[BM_elem_index_get(eed->v1)],
vertexCos[BM_elem_index_get(eed->v2)]);
positions[BM_elem_index_get(eed->v1)],
positions[BM_elem_index_get(eed->v2)]);
}
}
else {
@ -164,7 +160,7 @@ void BKE_mesh_foreach_mapped_loop(Mesh *mesh,
BMIter iter;
BMFace *efa;
const float(*vertexCos)[3] = mesh->runtime->edit_data->vertexCos;
const blender::Span<blender::float3> positions = mesh->runtime->edit_data->vertexCos;
/* XXX: investigate using EditMesh data. */
blender::Span<blender::float3> corner_normals;
@ -185,9 +181,11 @@ void BKE_mesh_foreach_mapped_loop(Mesh *mesh,
do {
const BMVert *eve = l_iter->v;
const int v_idx = BM_elem_index_get(eve);
const float *no = corner_normals.is_empty() ? nullptr :
&corner_normals[BM_elem_index_get(l_iter)].x;
func(userData, v_idx, f_idx, vertexCos ? vertexCos[v_idx] : eve->co, no);
func(userData,
v_idx,
f_idx,
positions.is_empty() ? positions[v_idx] : blender::float3(eve->co),
corner_normals.is_empty() ? nullptr : &corner_normals[BM_elem_index_get(l_iter)].x);
} while ((l_iter = l_iter->next) != l_first);
}
}
@ -243,33 +241,30 @@ void BKE_mesh_foreach_mapped_face_center(
if (mesh->edit_mesh != nullptr && mesh->runtime->edit_data != nullptr) {
BMEditMesh *em = mesh->edit_mesh;
BMesh *bm = em->bm;
const float(*polyCos)[3];
const float(*polyNos)[3];
blender::Span<blender::float3> poly_centers;
blender::Span<blender::float3> poly_normals;
BMFace *efa;
BMIter iter;
int i;
BKE_editmesh_cache_ensure_poly_centers(em, mesh->runtime->edit_data);
polyCos = mesh->runtime->edit_data->polyCos; /* always set */
poly_centers = mesh->runtime->edit_data->polyCos; /* always set */
if (flag & MESH_FOREACH_USE_NORMAL) {
BKE_editmesh_cache_ensure_poly_normals(em, mesh->runtime->edit_data);
polyNos = mesh->runtime->edit_data->polyNos; /* maybe nullptr */
}
else {
polyNos = nullptr;
poly_normals = mesh->runtime->edit_data->polyNos; /* maybe nullptr */
}
if (polyNos) {
if (!poly_normals.is_empty()) {
BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) {
const float *no = polyNos[i];
func(userData, i, polyCos[i], no);
const float *no = poly_normals[i];
func(userData, i, poly_centers[i], no);
}
}
else {
BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) {
const float *no = (flag & MESH_FOREACH_USE_NORMAL) ? efa->no : nullptr;
func(userData, i, polyCos[i], no);
func(userData, i, poly_centers[i], no);
}
}
}

View File

@ -362,8 +362,8 @@ void BKE_mesh_ensure_normals_for_display(Mesh *mesh)
break;
case ME_WRAPPER_TYPE_BMESH: {
BMEditMesh *em = mesh->edit_mesh;
if (EditMeshData *emd = mesh->runtime->edit_data) {
if (emd->vertexCos) {
if (blender::bke::EditMeshData *emd = mesh->runtime->edit_data) {
if (!emd->vertexCos.is_empty()) {
BKE_editmesh_cache_ensure_vert_normals(em, emd);
BKE_editmesh_cache_ensure_poly_normals(em, emd);
}

View File

@ -36,23 +36,6 @@ using blender::Span;
namespace blender::bke {
static void edit_data_reset(EditMeshData &edit_data)
{
MEM_SAFE_FREE(edit_data.polyCos);
MEM_SAFE_FREE(edit_data.polyNos);
MEM_SAFE_FREE(edit_data.vertexCos);
MEM_SAFE_FREE(edit_data.vertexNos);
}
static void free_edit_data(MeshRuntime &mesh_runtime)
{
if (mesh_runtime.edit_data) {
edit_data_reset(*mesh_runtime.edit_data);
MEM_freeN(mesh_runtime.edit_data);
mesh_runtime.edit_data = nullptr;
}
}
static void free_mesh_eval(MeshRuntime &mesh_runtime)
{
if (mesh_runtime.mesh_eval != nullptr) {
@ -100,7 +83,6 @@ MeshRuntime::~MeshRuntime()
free_mesh_eval(*this);
free_subdiv_ccg(*this);
free_bvh_cache(*this);
free_edit_data(*this);
free_batch_cache(*this);
if (this->shrinkwrap_data) {
BKE_shrinkwrap_boundary_data_free(this->shrinkwrap_data);
@ -266,15 +248,15 @@ bool BKE_mesh_runtime_ensure_edit_data(Mesh *mesh)
if (mesh->runtime->edit_data != nullptr) {
return false;
}
mesh->runtime->edit_data = MEM_cnew<EditMeshData>(__func__);
mesh->runtime->edit_data = MEM_new<blender::bke::EditMeshData>(__func__);
return true;
}
void BKE_mesh_runtime_reset_edit_data(Mesh *mesh)
{
using namespace blender::bke;
if (EditMeshData *edit_data = mesh->runtime->edit_data) {
edit_data_reset(*edit_data);
if (blender::bke::EditMeshData *edit_data = mesh->runtime->edit_data) {
*edit_data = {};
}
}
@ -283,7 +265,8 @@ void BKE_mesh_runtime_clear_cache(Mesh *mesh)
using namespace blender::bke;
free_mesh_eval(*mesh->runtime);
free_batch_cache(*mesh->runtime);
free_edit_data(*mesh->runtime);
MEM_delete(mesh->runtime->edit_data);
mesh->runtime->edit_data = nullptr;
BKE_mesh_runtime_clear_geometry(mesh);
}

View File

@ -124,13 +124,14 @@ void BKE_mesh_wrapper_ensure_mdata(Mesh *me)
* harmful. */
BKE_mesh_ensure_default_orig_index_customdata_no_check(me);
EditMeshData *edit_data = me->runtime->edit_data;
if (edit_data->vertexCos) {
BKE_mesh_vert_coords_apply(me, edit_data->vertexCos);
blender::bke::EditMeshData *edit_data = me->runtime->edit_data;
if (!edit_data->vertexCos.is_empty()) {
me->vert_positions_for_write().copy_from(edit_data->vertexCos);
me->runtime->is_original_bmesh = false;
}
BKE_mesh_runtime_reset_edit_data(me);
MEM_SAFE_FREE(me->runtime->edit_data);
MEM_delete(me->runtime->edit_data);
me->runtime->edit_data = nullptr;
break;
}
}
@ -173,7 +174,7 @@ const float (*BKE_mesh_wrapper_vert_coords(const Mesh *mesh))[3]
{
switch (mesh->runtime->wrapper_type) {
case ME_WRAPPER_TYPE_BMESH:
return mesh->runtime->edit_data->vertexCos;
return reinterpret_cast<const float(*)[3]>(mesh->runtime->edit_data->vertexCos.data());
case ME_WRAPPER_TYPE_MDATA:
case ME_WRAPPER_TYPE_SUBD:
return reinterpret_cast<const float(*)[3]>(mesh->vert_positions().data());
@ -186,7 +187,7 @@ const float (*BKE_mesh_wrapper_poly_normals(Mesh *mesh))[3]
switch (mesh->runtime->wrapper_type) {
case ME_WRAPPER_TYPE_BMESH:
BKE_editmesh_cache_ensure_poly_normals(mesh->edit_mesh, mesh->runtime->edit_data);
return mesh->runtime->edit_data->polyNos;
return reinterpret_cast<const float(*)[3]>(mesh->runtime->edit_data->polyNos.data());
case ME_WRAPPER_TYPE_MDATA:
case ME_WRAPPER_TYPE_SUBD:
return reinterpret_cast<const float(*)[3]>(mesh->poly_normals().data());
@ -199,9 +200,9 @@ void BKE_mesh_wrapper_tag_positions_changed(Mesh *mesh)
switch (mesh->runtime->wrapper_type) {
case ME_WRAPPER_TYPE_BMESH:
if (mesh->runtime->edit_data) {
MEM_SAFE_FREE(mesh->runtime->edit_data->vertexNos);
MEM_SAFE_FREE(mesh->runtime->edit_data->polyCos);
MEM_SAFE_FREE(mesh->runtime->edit_data->polyNos);
mesh->runtime->edit_data->vertexNos = {};
mesh->runtime->edit_data->polyCos = {};
mesh->runtime->edit_data->polyNos = {};
}
break;
case ME_WRAPPER_TYPE_MDATA:
@ -219,8 +220,8 @@ void BKE_mesh_wrapper_vert_coords_copy(const Mesh *me,
case ME_WRAPPER_TYPE_BMESH: {
BMesh *bm = me->edit_mesh->bm;
BLI_assert(vert_coords_len <= bm->totvert);
EditMeshData *edit_data = me->runtime->edit_data;
if (edit_data->vertexCos != nullptr) {
blender::bke::EditMeshData *edit_data = me->runtime->edit_data;
if (!edit_data->vertexCos.is_empty()) {
for (int i = 0; i < vert_coords_len; i++) {
copy_v3_v3(vert_coords[i], edit_data->vertexCos[i]);
}
@ -257,8 +258,8 @@ void BKE_mesh_wrapper_vert_coords_copy_with_mat4(const Mesh *me,
case ME_WRAPPER_TYPE_BMESH: {
BMesh *bm = me->edit_mesh->bm;
BLI_assert(vert_coords_len == bm->totvert);
EditMeshData *edit_data = me->runtime->edit_data;
if (edit_data->vertexCos != nullptr) {
const blender::bke::EditMeshData *edit_data = me->runtime->edit_data;
if (!edit_data->vertexCos.is_empty()) {
for (int i = 0; i < vert_coords_len; i++) {
mul_v3_m4v3(vert_coords[i], mat, edit_data->vertexCos[i]);
}

View File

@ -966,8 +966,8 @@ static void modwrap_dependsOnNormals(Mesh *me)
{
switch (me->runtime->wrapper_type) {
case ME_WRAPPER_TYPE_BMESH: {
EditMeshData *edit_data = me->runtime->edit_data;
if (edit_data->vertexCos) {
blender::bke::EditMeshData *edit_data = me->runtime->edit_data;
if (!edit_data->vertexCos.is_empty()) {
/* Note that 'ensure' is acceptable here since these values aren't modified in-place.
* If that changes we'll need to recalculate. */
BKE_editmesh_cache_ensure_vert_normals(me->edit_mesh, edit_data);

View File

@ -3329,7 +3329,8 @@ static void give_parvert(Object *par, int nr, float vec[3])
#endif
}
if (nr < numVerts) {
if (me_eval && me_eval->runtime->edit_data && me_eval->runtime->edit_data->vertexCos) {
if (me_eval && me_eval->runtime->edit_data &&
!me_eval->runtime->edit_data->vertexCos.is_empty()) {
add_v3_v3(vec, me_eval->runtime->edit_data->vertexCos[nr]);
}
else {

View File

@ -470,17 +470,17 @@ static const Mesh *mesh_data_from_duplicator_object(Object *ob,
* We could change this but it matches 2.7x behavior. */
me_eval = BKE_object_get_editmesh_eval_cage(ob);
if ((me_eval == nullptr) || (me_eval->runtime->wrapper_type == ME_WRAPPER_TYPE_BMESH)) {
EditMeshData *emd = me_eval ? me_eval->runtime->edit_data : nullptr;
blender::bke::EditMeshData *emd = me_eval ? me_eval->runtime->edit_data : nullptr;
/* Only assign edit-mesh in the case we can't use `me_eval`. */
*r_em = em;
me_eval = nullptr;
if ((emd != nullptr) && (emd->vertexCos != nullptr)) {
*r_vert_coords = emd->vertexCos;
if ((emd != nullptr) && !emd->vertexCos.is_empty()) {
*r_vert_coords = reinterpret_cast<const float(*)[3]>(emd->vertexCos.data());
if (r_vert_normals != nullptr) {
BKE_editmesh_cache_ensure_vert_normals(em, emd);
*r_vert_normals = emd->vertexNos;
*r_vert_normals = reinterpret_cast<const float(*)[3]>(emd->vertexNos.data());
}
}
}

View File

@ -369,10 +369,10 @@ void mesh_render_data_update_normals(MeshRenderData *mr, const eMRDataType data_
const float(*vert_normals)[3] = nullptr;
const float(*poly_normals)[3] = nullptr;
if (mr->edit_data && mr->edit_data->vertexCos) {
vert_coords = mr->bm_vert_coords;
vert_normals = mr->bm_vert_normals;
poly_normals = mr->bm_poly_normals;
if (mr->edit_data && !mr->edit_data->vertexCos.is_empty()) {
vert_coords = reinterpret_cast<const float(*)[3]>(mr->bm_vert_coords.data());
vert_normals = reinterpret_cast<const float(*)[3]>(mr->bm_vert_normals.data());
poly_normals = reinterpret_cast<const float(*)[3]>(mr->bm_poly_normals.data());
}
mr->loop_normals.reinitialize(mr->loop_len);
@ -431,8 +431,8 @@ MeshRenderData *mesh_render_data_create(Object *object,
mr->hide_unmapped_edges = !do_final || editmesh_eval_final == editmesh_eval_cage;
if (mr->edit_data) {
EditMeshData *emd = mr->edit_data;
if (emd->vertexCos) {
blender::bke::EditMeshData *emd = mr->edit_data;
if (!emd->vertexCos.is_empty()) {
BKE_editmesh_cache_ensure_vert_normals(mr->edit_bmesh, emd);
BKE_editmesh_cache_ensure_poly_normals(mr->edit_bmesh, emd);
}

View File

@ -59,14 +59,14 @@ struct MeshRenderData {
/** Edit Mesh */
BMEditMesh *edit_bmesh;
BMesh *bm;
EditMeshData *edit_data;
blender::bke::EditMeshData *edit_data;
/* For deformed edit-mesh data. */
/* Use for #ME_WRAPPER_TYPE_BMESH. */
const float (*bm_vert_coords)[3];
const float (*bm_vert_normals)[3];
const float (*bm_poly_normals)[3];
const float (*bm_poly_centers)[3];
blender::Span<blender::float3> bm_vert_coords;
blender::Span<blender::float3> bm_vert_normals;
blender::Span<blender::float3> bm_poly_normals;
blender::Span<blender::float3> bm_poly_centers;
const int *v_origindex, *e_origindex, *p_origindex;
int edge_crease_ofs;
@ -207,34 +207,25 @@ BLI_INLINE BMVert *bm_original_vert_get(const MeshRenderData *mr, int idx)
BLI_INLINE const float *bm_vert_co_get(const MeshRenderData *mr, const BMVert *eve)
{
const float(*vert_coords)[3] = mr->bm_vert_coords;
if (vert_coords != nullptr) {
return vert_coords[BM_elem_index_get(eve)];
if (!mr->bm_vert_coords.is_empty()) {
return mr->bm_vert_coords[BM_elem_index_get(eve)];
}
UNUSED_VARS(mr);
return eve->co;
}
BLI_INLINE const float *bm_vert_no_get(const MeshRenderData *mr, const BMVert *eve)
{
const float(*vert_normals)[3] = mr->bm_vert_normals;
if (vert_normals != nullptr) {
return vert_normals[BM_elem_index_get(eve)];
if (!mr->bm_vert_normals.is_empty()) {
return mr->bm_vert_normals[BM_elem_index_get(eve)];
}
UNUSED_VARS(mr);
return eve->no;
}
BLI_INLINE const float *bm_face_no_get(const MeshRenderData *mr, const BMFace *efa)
{
const float(*poly_normals)[3] = mr->bm_poly_normals;
if (poly_normals != nullptr) {
return poly_normals[BM_elem_index_get(efa)];
if (!mr->bm_poly_normals.is_empty()) {
return mr->bm_poly_normals[BM_elem_index_get(efa)];
}
UNUSED_VARS(mr);
return efa->no;
}

View File

@ -394,7 +394,7 @@ static void statvis_calc_distort(const MeshRenderData *mr, float *r_distort)
BMesh *bm = em->bm;
BMFace *f;
if (mr->bm_vert_coords != nullptr) {
if (!mr->bm_vert_coords.is_empty()) {
BKE_editmesh_cache_ensure_poly_normals(em, mr->edit_data);
/* Most likely this is already valid, ensure just in case.
@ -415,9 +415,13 @@ static void statvis_calc_distort(const MeshRenderData *mr, float *r_distort)
do {
const float *no_face;
float no_corner[3];
if (mr->bm_vert_coords != nullptr) {
if (!mr->bm_vert_coords.is_empty()) {
no_face = mr->bm_poly_normals[f_index];
BM_loop_calc_face_normal_safe_vcos(l_iter, no_face, mr->bm_vert_coords, no_corner);
BM_loop_calc_face_normal_safe_vcos(
l_iter,
no_face,
reinterpret_cast<const float(*)[3]>(mr->bm_vert_coords.data()),
no_corner);
}
else {
no_face = f->no;