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:
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 = {};
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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 */
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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. */
|
||||
|
||||
Reference in New Issue
Block a user