Cleanup: Store more mesh runtime data with unique_ptr

Convert shrinkwrap data arrays to use C++ arrays and BitVector,
use references in "EditMeshData" code, and store both structs
with `std::unique_ptr` instead of a raw allocation.
This commit is contained in:
Hans Goudey
2023-12-04 15:22:00 -05:00
parent 0318d49995
commit 695e626d3f
15 changed files with 89 additions and 122 deletions

View File

@@ -29,10 +29,10 @@ struct EditMeshData {
} // namespace blender::bke
void BKE_editmesh_cache_ensure_face_normals(BMEditMesh *em, blender::bke::EditMeshData *emd);
void BKE_editmesh_cache_ensure_vert_normals(BMEditMesh *em, blender::bke::EditMeshData *emd);
void BKE_editmesh_cache_ensure_face_normals(BMEditMesh &em, blender::bke::EditMeshData &emd);
void BKE_editmesh_cache_ensure_vert_normals(BMEditMesh &em, blender::bke::EditMeshData &emd);
void BKE_editmesh_cache_ensure_face_centers(BMEditMesh *em, blender::bke::EditMeshData *emd);
void BKE_editmesh_cache_ensure_face_centers(BMEditMesh &em, blender::bke::EditMeshData &emd);
std::optional<blender::Bounds<blender::float3>> BKE_editmesh_cache_calc_minmax(
const BMEditMesh *em, const blender::bke::EditMeshData *emd);
const BMEditMesh &em, const blender::bke::EditMeshData &emd);

View File

@@ -23,7 +23,7 @@ struct Scene;
/** Return the number of derived triangles (looptris). */
int BKE_mesh_runtime_looptri_len(const Mesh *mesh);
bool BKE_mesh_runtime_ensure_edit_data(Mesh *mesh);
void BKE_mesh_runtime_ensure_edit_data(Mesh *mesh);
/**
* Clear and free any derived caches associated with the mesh geometry data. Examples include BVH

View File

@@ -117,7 +117,7 @@ struct MeshRuntime {
* Lazily initialized SoA data from the #edit_mesh field in #Mesh. Used when the mesh is a BMesh
* wrapper (#ME_WRAPPER_TYPE_BMESH).
*/
EditMeshData *edit_data = nullptr;
std::unique_ptr<EditMeshData> edit_data;
/**
* Data used to efficiently draw the mesh in the viewport, especially useful when
@@ -134,7 +134,7 @@ struct MeshRuntime {
BVHCache *bvh_cache = nullptr;
/** Cache of non-manifold boundary data for Shrink-wrap Target Project. */
ShrinkwrapBoundaryData *shrinkwrap_data = nullptr;
std::unique_ptr<ShrinkwrapBoundaryData> shrinkwrap_data;
/** Needed in case we need to lazily initialize the mesh. */
CustomData_MeshMasks cd_mask_extra = {};

View File

@@ -9,8 +9,9 @@
/* Shrinkwrap stuff */
#include "BKE_bvhutils.hh"
#include "BLI_bitmap.h"
#include "BLI_array.hh"
#include "BLI_bit_vector.hh"
#include "BLI_math_vector_types.hh"
#include "BLI_offset_indices.hh"
#include "BLI_span.hh"
@@ -48,23 +49,21 @@ struct ShrinkwrapBoundaryVertData {
struct ShrinkwrapBoundaryData {
/* True if the edge belongs to exactly one face. */
const BLI_bitmap *edge_is_boundary;
blender::BitVector<> edge_is_boundary;
/* True if the looptri has any boundary edges. */
const BLI_bitmap *looptri_has_boundary;
blender::BitVector<> looptri_has_boundary;
/* Mapping from vertex index to boundary vertex index, or -1.
* Used for compact storage of data about boundary vertices. */
const int *vert_boundary_id;
unsigned int num_boundary_verts;
blender::Array<int> vert_boundary_id;
/* Direction data about boundary vertices. */
const ShrinkwrapBoundaryVertData *boundary_verts;
blender::Array<ShrinkwrapBoundaryVertData> boundary_verts;
};
/**
* Free boundary data for target project.
*/
void BKE_shrinkwrap_boundary_data_free(ShrinkwrapBoundaryData *data);
void BKE_shrinkwrap_compute_boundary_data(Mesh *mesh);
/* Information about a mesh and BVH tree. */

View File

@@ -1035,9 +1035,9 @@ static void editbmesh_calc_modifier_final_normals(Mesh *mesh_final)
case ME_WRAPPER_TYPE_MDATA:
break;
case ME_WRAPPER_TYPE_BMESH: {
BMEditMesh *em = mesh_final->edit_mesh;
blender::bke::EditMeshData *emd = mesh_final->runtime->edit_data;
if (!emd->vertexCos.is_empty()) {
BMEditMesh &em = *mesh_final->edit_mesh;
blender::bke::EditMeshData &emd = *mesh_final->runtime->edit_data;
if (!emd.vertexCos.is_empty()) {
BKE_editmesh_cache_ensure_vert_normals(em, emd);
BKE_editmesh_cache_ensure_face_normals(em, emd);
}

View File

@@ -23,14 +23,14 @@
/** \name Ensure Data (derived from coords)
* \{ */
void BKE_editmesh_cache_ensure_face_normals(BMEditMesh *em, blender::bke::EditMeshData *emd)
void BKE_editmesh_cache_ensure_face_normals(BMEditMesh &em, blender::bke::EditMeshData &emd)
{
if (emd->vertexCos.is_empty() || !emd->faceNos.is_empty()) {
if (emd.vertexCos.is_empty() || !emd.faceNos.is_empty()) {
return;
}
BMesh *bm = em->bm;
BMesh *bm = em.bm;
emd->faceNos.reinitialize(bm->totface);
emd.faceNos.reinitialize(bm->totface);
BM_mesh_elem_index_ensure(bm, BM_VERT);
BMFace *efa;
@@ -39,52 +39,52 @@ void BKE_editmesh_cache_ensure_face_normals(BMEditMesh *em, blender::bke::EditMe
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, emd->faceNos[i], reinterpret_cast<const float(*)[3]>(emd->vertexCos.data()));
bm, efa, emd.faceNos[i], reinterpret_cast<const float(*)[3]>(emd.vertexCos.data()));
}
bm->elem_index_dirty &= ~BM_FACE;
}
void BKE_editmesh_cache_ensure_vert_normals(BMEditMesh *em, blender::bke::EditMeshData *emd)
void BKE_editmesh_cache_ensure_vert_normals(BMEditMesh &em, blender::bke::EditMeshData &emd)
{
if (emd->vertexCos.is_empty() || !emd->vertexNos.is_empty()) {
if (emd.vertexCos.is_empty() || !emd.vertexNos.is_empty()) {
return;
}
BMesh *bm = em->bm;
BMesh *bm = em.bm;
/* Calculate vertex normals from face normals. */
BKE_editmesh_cache_ensure_face_normals(em, emd);
emd->vertexNos.reinitialize(bm->totvert);
emd.vertexNos.reinitialize(bm->totvert);
BM_mesh_elem_index_ensure(bm, BM_FACE);
BM_verts_calc_normal_vcos(bm,
reinterpret_cast<const float(*)[3]>(emd->faceNos.data()),
reinterpret_cast<const float(*)[3]>(emd->vertexCos.data()),
reinterpret_cast<float(*)[3]>(emd->vertexNos.data()));
reinterpret_cast<const float(*)[3]>(emd.faceNos.data()),
reinterpret_cast<const float(*)[3]>(emd.vertexCos.data()),
reinterpret_cast<float(*)[3]>(emd.vertexNos.data()));
}
void BKE_editmesh_cache_ensure_face_centers(BMEditMesh *em, blender::bke::EditMeshData *emd)
void BKE_editmesh_cache_ensure_face_centers(BMEditMesh &em, blender::bke::EditMeshData &emd)
{
if (!emd->faceCos.is_empty()) {
if (!emd.faceCos.is_empty()) {
return;
}
BMesh *bm = em->bm;
BMesh *bm = em.bm;
emd->faceCos.reinitialize(bm->totface);
emd.faceCos.reinitialize(bm->totface);
BMFace *efa;
BMIter fiter;
int i;
if (emd->vertexCos.is_empty()) {
if (emd.vertexCos.is_empty()) {
BM_ITER_MESH_INDEX (efa, &fiter, bm, BM_FACES_OF_MESH, i) {
BM_face_calc_center_median(efa, emd->faceCos[i]);
BM_face_calc_center_median(efa, emd.faceCos[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_vcos(
bm, efa, emd->faceCos[i], reinterpret_cast<const float(*)[3]>(emd->vertexCos.data()));
bm, efa, emd.faceCos[i], reinterpret_cast<const float(*)[3]>(emd.vertexCos.data()));
}
}
}
@@ -96,15 +96,15 @@ void BKE_editmesh_cache_ensure_face_centers(BMEditMesh *em, blender::bke::EditMe
* \{ */
std::optional<blender::Bounds<blender::float3>> BKE_editmesh_cache_calc_minmax(
const BMEditMesh *em, const blender::bke::EditMeshData *emd)
const BMEditMesh &em, const blender::bke::EditMeshData &emd)
{
using namespace blender;
BMesh *bm = em->bm;
BMesh *bm = em.bm;
if (bm->totvert == 0) {
return std::nullopt;
}
if (emd->vertexCos.is_empty()) {
if (emd.vertexCos.is_empty()) {
BMVert *eve;
BMIter iter;
float3 min(std::numeric_limits<float>::max());
@@ -115,7 +115,7 @@ std::optional<blender::Bounds<blender::float3>> BKE_editmesh_cache_calc_minmax(
return Bounds<float3>{min, max};
}
return bounds::min_max(emd->vertexCos.as_span());
return bounds::min_max(emd.vertexCos.as_span());
}
/** \} */

View File

@@ -1090,7 +1090,7 @@ std::optional<blender::Bounds<blender::float3>> Mesh::bounds_min_max() const
this->runtime->bounds_cache.ensure([&](Bounds<float3> &r_bounds) {
switch (this->runtime->wrapper_type) {
case ME_WRAPPER_TYPE_BMESH:
r_bounds = *BKE_editmesh_cache_calc_minmax(this->edit_mesh, this->runtime->edit_data);
r_bounds = *BKE_editmesh_cache_calc_minmax(*this->edit_mesh, *this->runtime->edit_data);
break;
case ME_WRAPPER_TYPE_MDATA:
case ME_WRAPPER_TYPE_SUBD:

View File

@@ -48,7 +48,7 @@ void BKE_mesh_foreach_mapped_vert(
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);
BKE_editmesh_cache_ensure_vert_normals(*em, *mesh->runtime->edit_data);
vert_normals = mesh->runtime->edit_data->vertexNos;
}
BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
@@ -245,11 +245,11 @@ void BKE_mesh_foreach_mapped_face_center(
BMIter iter;
int i;
BKE_editmesh_cache_ensure_face_centers(em, mesh->runtime->edit_data);
BKE_editmesh_cache_ensure_face_centers(*em, *mesh->runtime->edit_data);
face_centers = mesh->runtime->edit_data->faceCos; /* always set */
if (flag & MESH_FOREACH_USE_NORMAL) {
BKE_editmesh_cache_ensure_face_normals(em, mesh->runtime->edit_data);
BKE_editmesh_cache_ensure_face_normals(*em, *mesh->runtime->edit_data);
face_normals = mesh->runtime->edit_data->faceNos; /* maybe nullptr */
}

View File

@@ -70,9 +70,6 @@ MeshRuntime::~MeshRuntime()
free_mesh_eval(*this);
free_bvh_cache(*this);
free_batch_cache(*this);
if (this->shrinkwrap_data) {
BKE_shrinkwrap_boundary_data_free(this->shrinkwrap_data);
}
}
static int reset_bits_and_count(MutableBitSpan bits, const Span<int> indices_to_reset)
@@ -282,13 +279,11 @@ void BKE_mesh_runtime_verttri_from_looptri(MVertTri *r_verttri,
}
}
bool BKE_mesh_runtime_ensure_edit_data(Mesh *mesh)
void BKE_mesh_runtime_ensure_edit_data(Mesh *mesh)
{
if (mesh->runtime->edit_data != nullptr) {
return false;
if (!mesh->runtime->edit_data) {
mesh->runtime->edit_data = std::make_unique<blender::bke::EditMeshData>();
}
mesh->runtime->edit_data = MEM_new<blender::bke::EditMeshData>(__func__);
return true;
}
void BKE_mesh_runtime_clear_cache(Mesh *mesh)
@@ -296,8 +291,7 @@ void BKE_mesh_runtime_clear_cache(Mesh *mesh)
using namespace blender::bke;
free_mesh_eval(*mesh->runtime);
free_batch_cache(*mesh->runtime);
MEM_delete(mesh->runtime->edit_data);
mesh->runtime->edit_data = nullptr;
mesh->runtime->edit_data.reset();
BKE_mesh_runtime_clear_geometry(mesh);
}
@@ -320,10 +314,7 @@ void BKE_mesh_runtime_clear_geometry(Mesh *mesh)
mesh->runtime->looptri_faces_cache.tag_dirty();
mesh->runtime->subsurf_face_dot_tags.clear_and_shrink();
mesh->runtime->subsurf_optimal_display_edges.clear_and_shrink();
if (mesh->runtime->shrinkwrap_data) {
BKE_shrinkwrap_boundary_data_free(mesh->runtime->shrinkwrap_data);
mesh->runtime->shrinkwrap_data = nullptr;
}
mesh->runtime->shrinkwrap_data.reset();
mesh->flag &= ~ME_NO_OVERLAPPING_TOPOLOGY;
}
@@ -353,10 +344,7 @@ void BKE_mesh_tag_edges_split(Mesh *mesh)
}
mesh->runtime->subsurf_face_dot_tags.clear_and_shrink();
mesh->runtime->subsurf_optimal_display_edges.clear_and_shrink();
if (mesh->runtime->shrinkwrap_data) {
BKE_shrinkwrap_boundary_data_free(mesh->runtime->shrinkwrap_data);
mesh->runtime->shrinkwrap_data = nullptr;
}
mesh->runtime->shrinkwrap_data.reset();
}
void BKE_mesh_tag_sharpness_changed(Mesh *mesh)

View File

@@ -125,9 +125,9 @@ void BKE_mesh_wrapper_ensure_mdata(Mesh *me)
* be wrong, but it's not harmful. */
BKE_mesh_ensure_default_orig_index_customdata_no_check(me);
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);
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;
}
@@ -135,8 +135,7 @@ void BKE_mesh_wrapper_ensure_mdata(Mesh *me)
BKE_mesh_wrapper_deferred_finalize_mdata(me);
}
MEM_delete(me->runtime->edit_data);
me->runtime->edit_data = nullptr;
me->runtime->edit_data.reset();
break;
}
}
@@ -170,7 +169,7 @@ const float (*BKE_mesh_wrapper_face_normals(Mesh *mesh))[3]
{
switch (mesh->runtime->wrapper_type) {
case ME_WRAPPER_TYPE_BMESH:
BKE_editmesh_cache_ensure_face_normals(mesh->edit_mesh, mesh->runtime->edit_data);
BKE_editmesh_cache_ensure_face_normals(*mesh->edit_mesh, *mesh->runtime->edit_data);
if (mesh->runtime->edit_data->faceNos.is_empty()) {
return nullptr;
}
@@ -204,9 +203,9 @@ void BKE_mesh_wrapper_vert_coords_copy(const Mesh *me, blender::MutableSpan<floa
switch (me->runtime->wrapper_type) {
case ME_WRAPPER_TYPE_BMESH: {
BMesh *bm = me->edit_mesh->bm;
blender::bke::EditMeshData *edit_data = me->runtime->edit_data;
if (!edit_data->vertexCos.is_empty()) {
positions.copy_from(edit_data->vertexCos);
const blender::bke::EditMeshData &edit_data = *me->runtime->edit_data;
if (!edit_data.vertexCos.is_empty()) {
positions.copy_from(edit_data.vertexCos);
}
else {
BMIter iter;
@@ -236,10 +235,10 @@ 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);
const blender::bke::EditMeshData *edit_data = me->runtime->edit_data;
if (!edit_data->vertexCos.is_empty()) {
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]);
mul_v3_m4v3(vert_coords[i], mat, edit_data.vertexCos[i]);
}
}
else {

View File

@@ -965,11 +965,11 @@ static void modwrap_dependsOnNormals(Mesh *me)
{
switch (me->runtime->wrapper_type) {
case ME_WRAPPER_TYPE_BMESH: {
blender::bke::EditMeshData *edit_data = me->runtime->edit_data;
if (!edit_data->vertexCos.is_empty()) {
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);
BKE_editmesh_cache_ensure_vert_normals(*me->edit_mesh, edit_data);
}
else {
BM_mesh_normals_update(me->edit_mesh->bm);

View File

@@ -478,7 +478,7 @@ 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)) {
blender::bke::EditMeshData *emd = me_eval ? me_eval->runtime->edit_data : nullptr;
blender::bke::EditMeshData *emd = me_eval ? me_eval->runtime->edit_data.get() : nullptr;
/* Only assign edit-mesh in the case we can't use `me_eval`. */
*r_em = em;
@@ -487,7 +487,7 @@ static const Mesh *mesh_data_from_duplicator_object(Object *ob,
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);
BKE_editmesh_cache_ensure_vert_normals(*em, *emd);
*r_vert_normals = reinterpret_cast<const float(*)[3]>(emd->vertexNos.data());
}
}

View File

@@ -148,7 +148,7 @@ bool BKE_shrinkwrap_init_tree(
}
if (shrinkType == MOD_SHRINKWRAP_TARGET_PROJECT) {
data->boundary = mesh->runtime->shrinkwrap_data;
data->boundary = mesh->runtime->shrinkwrap_data.get();
}
return true;
@@ -159,16 +159,6 @@ void BKE_shrinkwrap_free_tree(ShrinkwrapTreeData *data)
free_bvhtree_from_mesh(&data->treeData);
}
void BKE_shrinkwrap_boundary_data_free(ShrinkwrapBoundaryData *data)
{
MEM_freeN((void *)data->edge_is_boundary);
MEM_freeN((void *)data->looptri_has_boundary);
MEM_freeN((void *)data->vert_boundary_id);
MEM_freeN((void *)data->boundary_verts);
MEM_freeN(data);
}
/* Accumulate edge for average boundary edge direction. */
static void merge_vert_dir(ShrinkwrapBoundaryVertData *vdata,
signed char *status,
@@ -193,7 +183,7 @@ static void merge_vert_dir(ShrinkwrapBoundaryVertData *vdata,
status[index] = (status[index] == 0) ? side : -1;
}
static ShrinkwrapBoundaryData *shrinkwrap_build_boundary_data(Mesh *mesh)
static std::unique_ptr<ShrinkwrapBoundaryData> shrinkwrap_build_boundary_data(Mesh *mesh)
{
using namespace blender;
const blender::Span<float3> positions = mesh->vert_positions();
@@ -214,36 +204,33 @@ static ShrinkwrapBoundaryData *shrinkwrap_build_boundary_data(Mesh *mesh)
}
/* Build the boundary edge bitmask. */
BLI_bitmap *edge_is_boundary = BLI_BITMAP_NEW(mesh->totedge,
"ShrinkwrapBoundaryData::edge_is_boundary");
blender::BitVector<> edge_is_boundary(mesh->totedge, false);
uint num_boundary_edges = 0;
for (int i = 0; i < mesh->totedge; i++) {
edge_mode[i] = (edge_mode[i] == 1);
if (edge_mode[i]) {
BLI_BITMAP_ENABLE(edge_is_boundary, i);
edge_is_boundary[i].set();
num_boundary_edges++;
}
}
/* If no boundary, return nullptr. */
if (num_boundary_edges == 0) {
MEM_freeN(edge_is_boundary);
MEM_freeN(edge_mode);
return nullptr;
return {};
}
/* Allocate the data object. */
ShrinkwrapBoundaryData *data = MEM_cnew<ShrinkwrapBoundaryData>(__func__);
std::unique_ptr<ShrinkwrapBoundaryData> data = std::make_unique<ShrinkwrapBoundaryData>();
data->edge_is_boundary = edge_is_boundary;
data->edge_is_boundary = std::move(edge_is_boundary);
/* Build the boundary looptri bitmask. */
const blender::Span<MLoopTri> looptris = mesh->looptris();
BLI_bitmap *looptri_has_boundary = BLI_BITMAP_NEW(looptris.size(),
"ShrinkwrapBoundaryData::looptri_is_boundary");
blender::BitVector<> looptri_has_boundary(looptris.size(), false);
for (const int64_t i : looptris.index_range()) {
const int3 real_edges = bke::mesh::looptri_get_real_edges(
@@ -251,17 +238,16 @@ static ShrinkwrapBoundaryData *shrinkwrap_build_boundary_data(Mesh *mesh)
for (int j = 0; j < 3; j++) {
if (real_edges[j] >= 0 && edge_mode[real_edges[j]]) {
BLI_BITMAP_ENABLE(looptri_has_boundary, i);
looptri_has_boundary[i].set();
break;
}
}
}
data->looptri_has_boundary = looptri_has_boundary;
data->looptri_has_boundary = std::move(looptri_has_boundary);
/* Find boundary vertices and build a mapping table for compact storage of data. */
int *vert_boundary_id = static_cast<int *>(
MEM_calloc_arrayN(size_t(mesh->totvert), sizeof(int), __func__));
Array<int> vert_boundary_id(mesh->totvert, 0);
for (int i = 0; i < mesh->totedge; i++) {
if (edge_mode[i]) {
@@ -279,11 +265,9 @@ static ShrinkwrapBoundaryData *shrinkwrap_build_boundary_data(Mesh *mesh)
}
data->vert_boundary_id = vert_boundary_id;
data->num_boundary_verts = num_boundary_verts;
/* Compute average directions. */
ShrinkwrapBoundaryVertData *boundary_verts = static_cast<ShrinkwrapBoundaryVertData *>(
MEM_calloc_arrayN(num_boundary_verts, sizeof(*boundary_verts), __func__));
Array<ShrinkwrapBoundaryVertData> boundary_verts(num_boundary_verts);
signed char *vert_status = static_cast<signed char *>(
MEM_calloc_arrayN(num_boundary_verts, sizeof(char), __func__));
@@ -296,8 +280,8 @@ static ShrinkwrapBoundaryData *shrinkwrap_build_boundary_data(Mesh *mesh)
sub_v3_v3v3(dir, positions[edge[1]], positions[edge[0]]);
normalize_v3(dir);
merge_vert_dir(boundary_verts, vert_status, vert_boundary_id[edge[0]], dir, 1);
merge_vert_dir(boundary_verts, vert_status, vert_boundary_id[edge[1]], dir, 2);
merge_vert_dir(boundary_verts.data(), vert_status, vert_boundary_id[edge[0]], dir, 1);
merge_vert_dir(boundary_verts.data(), vert_status, vert_boundary_id[edge[1]], dir, 2);
}
}
@@ -320,7 +304,7 @@ static ShrinkwrapBoundaryData *shrinkwrap_build_boundary_data(Mesh *mesh)
}
}
data->boundary_verts = boundary_verts;
data->boundary_verts = std::move(boundary_verts);
MEM_freeN(edge_mode);
return data;
@@ -328,9 +312,6 @@ static ShrinkwrapBoundaryData *shrinkwrap_build_boundary_data(Mesh *mesh)
void BKE_shrinkwrap_compute_boundary_data(Mesh *mesh)
{
if (mesh->runtime->shrinkwrap_data) {
BKE_shrinkwrap_boundary_data_free(mesh->runtime->shrinkwrap_data);
}
mesh->runtime->shrinkwrap_data = shrinkwrap_build_boundary_data(mesh);
}
@@ -957,7 +938,7 @@ static void target_project_edge(const ShrinkwrapTreeData *tree,
#endif
/* Retrieve boundary vertex IDs */
const int *vert_boundary_id = tree->boundary->vert_boundary_id;
const int *vert_boundary_id = tree->boundary->vert_boundary_id.data();
int bid1 = vert_boundary_id[edge[0]], bid2 = vert_boundary_id[edge[1]];
if (bid1 < 0 || bid2 < 0) {
@@ -965,7 +946,7 @@ static void target_project_edge(const ShrinkwrapTreeData *tree,
}
/* Retrieve boundary vertex normals and align them to direction. */
const ShrinkwrapBoundaryVertData *boundary_verts = tree->boundary->boundary_verts;
const ShrinkwrapBoundaryVertData *boundary_verts = tree->boundary->boundary_verts.data();
float vedge_dir[2][3], dir[3];
copy_v3_v3(vedge_dir[0], boundary_verts[bid1].normal_plane);
@@ -1060,13 +1041,13 @@ static void mesh_looptri_target_project(void *userdata,
update_hit(nearest, index, co, hit_co, hit_no);
}
/* Boundary edges */
else if (tree->boundary && BLI_BITMAP_TEST(tree->boundary->looptri_has_boundary, index)) {
const BLI_bitmap *is_boundary = tree->boundary->edge_is_boundary;
else if (tree->boundary && tree->boundary->looptri_has_boundary[index]) {
const BitSpan is_boundary = tree->boundary->edge_is_boundary;
const int3 edges = bke::mesh::looptri_get_real_edges(
data->edges, data->corner_verts, tree->corner_edges, *lt);
for (int i = 0; i < 3; i++) {
if (edges[i] >= 0 && BLI_BITMAP_TEST(is_boundary, edges[i])) {
if (edges[i] >= 0 && is_boundary[edges[i]]) {
target_project_edge(tree, index, co, nearest, edges[i]);
}
}

View File

@@ -489,7 +489,7 @@ MeshRenderData *mesh_render_data_create(Object *object,
mr->bm = me->edit_mesh->bm;
mr->edit_bmesh = me->edit_mesh;
mr->me = (do_final) ? editmesh_eval_final : editmesh_eval_cage;
mr->edit_data = is_mode_active ? mr->me->runtime->edit_data : nullptr;
mr->edit_data = is_mode_active ? mr->me->runtime->edit_data.get() : nullptr;
/* If there is no distinct cage, hide unmapped edges that can't be selected. */
mr->hide_unmapped_edges = !do_final || editmesh_eval_final == editmesh_eval_cage;
@@ -497,8 +497,8 @@ MeshRenderData *mesh_render_data_create(Object *object,
if (mr->edit_data) {
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_face_normals(mr->edit_bmesh, emd);
BKE_editmesh_cache_ensure_vert_normals(*mr->edit_bmesh, *emd);
BKE_editmesh_cache_ensure_face_normals(*mr->edit_bmesh, *emd);
}
mr->bm_vert_coords = mr->edit_data->vertexCos;

View File

@@ -397,7 +397,7 @@ static void statvis_calc_distort(const MeshRenderData &mr, float *r_distort)
BMFace *f;
if (!mr.bm_vert_coords.is_empty()) {
BKE_editmesh_cache_ensure_face_normals(em, mr.edit_data);
BKE_editmesh_cache_ensure_face_normals(*em, *mr.edit_data);
/* Most likely this is already valid, ensure just in case.
* Needed for #BM_loop_calc_face_normal_safe_vcos. */