Mesh: Cache loose vertices #105567

Merged
Hans Goudey merged 29 commits from HooglyBoogly/blender:mesh-loose-vert-cache into main 2023-04-22 13:46:23 +02:00
15 changed files with 29 additions and 26 deletions
Showing only changes of commit 011042e179 - Show all commits

View File

@ -82,6 +82,9 @@ struct LooseGeomCache {
int count = -1;
};
using LooseEdgeCache = LooseGeomCache;
using LooseVertCache = LooseGeomCache;
struct MeshRuntime {
/* Evaluated mesh for objects which do not have effective modifiers.
* This mesh is used as a result of modifier stack evaluation.
@ -166,8 +169,8 @@ struct MeshRuntime {
* A cache of data about the loose edges/verts. Can be shared with other data-blocks with
* unchanged topology. Accessed with #Mesh::loose_edges()/loose_verts().
*/
SharedCache<LooseGeomCache> loose_edges_cache;
SharedCache<LooseGeomCache> loose_verts_cache;
SharedCache<LooseEdgeCache> loose_edges_cache;
SharedCache<LooseVertCache> loose_verts_cache;
/**
* A bit vector the size of the number of vertices, set to true for the center vertices of

View File

@ -1168,7 +1168,7 @@ static BitVector<> loose_verts_map_get(const Span<MEdge> edges,
static BitVector<> loose_edges_map_get(const Mesh &mesh, int *r_loose_edge_len)
{
using namespace blender::bke;
const LooseGeomCache &loose_edges = mesh.loose_edges();
const LooseEdgeCache &loose_edges = mesh.loose_edges();
*r_loose_edge_len = loose_edges.count;
return loose_edges.is_loose_bits;
}

View File

@ -1605,7 +1605,7 @@ static bool cloth_build_springs(ClothModifierData *clmd, Mesh *mesh)
}
/* Structural springs. */
const LooseGeomCache &loose_edges = mesh->loose_edges();
const LooseEdgeCache &loose_edges = mesh->loose_edges();
for (int i = 0; i < numedges; i++) {
spring = (ClothSpring *)MEM_callocN(sizeof(ClothSpring), "cloth spring");

View File

@ -202,7 +202,7 @@ void adapt_mesh_domain_corner_to_point_impl(const Mesh &mesh,
}
/* Deselect loose vertices without corners that are still selected from the 'true' default. */
const bke::LooseGeomCache &loose_verts = mesh.loose_verts();
const bke::LooseVertCache &loose_verts = mesh.loose_verts();
if (loose_verts.count > 0) {
const BitSpan loose = loose_verts.is_loose_bits;
threading::parallel_for(loose.index_range(), 2048, [loose, r_values](const IndexRange range) {
@ -342,7 +342,7 @@ void adapt_mesh_domain_corner_to_edge_impl(const Mesh &mesh,
}
}
const bke::LooseGeomCache &loose_edges = mesh.loose_edges();
const bke::LooseEdgeCache &loose_edges = mesh.loose_edges();
if (loose_edges.count > 0) {
/* Deselect loose edges without corners that are still selected from the 'true' default. */
threading::parallel_for(IndexRange(mesh.totedge), 2048, [&](const IndexRange range) {

View File

@ -1947,7 +1947,7 @@ void BKE_mesh_legacy_convert_loose_edges_to_flag(Mesh *mesh)
using namespace blender;
using namespace blender::bke;
const LooseGeomCache &loose_edges = mesh->loose_edges();
const LooseEdgeCache &loose_edges = mesh->loose_edges();
MutableSpan<MEdge> edges = mesh->edges_for_write();
threading::parallel_for(edges.index_range(), 4096, [&](const IndexRange range) {
if (loose_edges.count == 0) {

View File

@ -108,10 +108,10 @@ MeshRuntime::~MeshRuntime()
} // namespace blender::bke
const blender::bke::LooseGeomCache &Mesh::loose_verts() const
const blender::bke::LooseVertCache &Mesh::loose_verts() const
{
using namespace blender::bke;
this->runtime->loose_verts_cache.ensure([&](LooseGeomCache &r_data) {
this->runtime->loose_verts_cache.ensure([&](LooseVertCache &r_data) {
// SCOPED_TIMER_AVERAGED("loose_verts");
blender::BitVector<> &loose_verts = r_data.is_loose_bits;
loose_verts.resize(0);
@ -137,10 +137,10 @@ const blender::bke::LooseGeomCache &Mesh::loose_verts() const
return this->runtime->loose_verts_cache.data();
}
const blender::bke::LooseGeomCache &Mesh::loose_edges() const
const blender::bke::LooseEdgeCache &Mesh::loose_edges() const
{
using namespace blender::bke;
this->runtime->loose_edges_cache.ensure([&](LooseGeomCache &r_data) {
this->runtime->loose_edges_cache.ensure([&](LooseEdgeCache &r_data) {
// SCOPED_TIMER_AVERAGED("loose_edges");
blender::BitVector<> &loose_edges = r_data.is_loose_bits;
loose_edges.resize(0);
@ -165,7 +165,7 @@ const blender::bke::LooseGeomCache &Mesh::loose_edges() const
void Mesh::loose_verts_tag_none() const
{
using namespace blender::bke;
this->runtime->loose_verts_cache.ensure([&](LooseGeomCache &r_data) {
this->runtime->loose_verts_cache.ensure([&](LooseVertCache &r_data) {
r_data.is_loose_bits.clear_and_shrink();
r_data.count = 0;
});
@ -174,7 +174,7 @@ void Mesh::loose_verts_tag_none() const
void Mesh::loose_edges_tag_none() const
{
using namespace blender::bke;
this->runtime->loose_edges_cache.ensure([&](LooseGeomCache &r_data) {
this->runtime->loose_edges_cache.ensure([&](LooseEdgeCache &r_data) {
r_data.is_loose_bits.clear_and_shrink();
r_data.count = 0;
});

View File

@ -359,8 +359,8 @@ static void initialize_manifold_indices(ConverterStorage *storage)
using namespace blender;
const Mesh *mesh = storage->mesh;
const blender::Span<MEdge> edges = storage->edges;
const bke::LooseGeomCache &loose_verts = mesh->loose_verts();
const bke::LooseGeomCache &loose_edges = mesh->loose_edges();
const bke::LooseVertCache &loose_verts = mesh->loose_verts();
const bke::LooseEdgeCache &loose_edges = mesh->loose_edges();
initialize_manifold_index_array(loose_verts.is_loose_bits,
mesh->totvert,
&storage->manifold_vertex_index,

View File

@ -33,7 +33,7 @@
static void mesh_render_data_loose_geom_mesh(const MeshRenderData *mr, MeshBufferCache *cache)
{
using namespace blender;
const bke::LooseGeomCache &loose_edges = mr->me->loose_edges();
const bke::LooseEdgeCache &loose_edges = mr->me->loose_edges();
if (loose_edges.count > 0) {
cache->loose_geom.edges.reinitialize(loose_edges.count);
@ -46,7 +46,7 @@ static void mesh_render_data_loose_geom_mesh(const MeshRenderData *mr, MeshBuffe
}
}
const bke::LooseGeomCache &loose_verts = mr->me->loose_verts();
const bke::LooseVertCache &loose_verts = mr->me->loose_verts();
if (loose_verts.count > 0) {
cache->loose_geom.verts.reinitialize(loose_verts.count);

View File

@ -1127,7 +1127,7 @@ void ED_mesh_update(Mesh *mesh, bContext *C, bool calc_edges, bool calc_edges_lo
bool ED_mesh_edge_is_loose(const Mesh *mesh, const int index)
{
using namespace blender;
const bke::LooseGeomCache &loose_edges = mesh->loose_edges();
const bke::LooseEdgeCache &loose_edges = mesh->loose_edges();
return loose_edges.count > 0 && loose_edges.is_loose_bits[index];
}

View File

@ -1788,7 +1788,7 @@ std::optional<Mesh *> mesh_merge_by_distance_connected(const Mesh &mesh,
range_vn_i(vert_dest_map.data(), mesh.totvert, 0);
/* Collapse Edges that are shorter than the threshold. */
const bke::LooseGeomCache *loose_edges = nullptr;
const bke::LooseEdgeCache *loose_edges = nullptr;
if (only_loose_edges) {
loose_edges = &mesh.loose_edges();
if (loose_edges->count == 0) {

View File

@ -2139,7 +2139,7 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info,
if (la_data->conf.use_loose) {
/* Only identifying floating edges at this point because other edges has been taken care of
* inside #lineart_identify_mlooptri_feature_edges function. */
const bke::LooseGeomCache &loose_edges = me->loose_edges();
const bke::LooseEdgeCache &loose_edges = me->loose_edges();
loose_data.loose_array = static_cast<int *>(
MEM_malloc_arrayN(loose_edges.count, sizeof(int), __func__));
if (loose_edges.count > 0) {

View File

@ -211,7 +211,7 @@ void GeometryExporter::createLooseEdgeList(Object *ob, Mesh *me, std::string &ge
/* Find all loose edges in Mesh
* and save vertex indices in edge_list */
const bke::LooseGeomCache &loose_edges = me->loose_edges();
const bke::LooseEdgeCache &loose_edges = me->loose_edges();
if (loose_edges.count > 0) {
for (const int64_t i : edges.index_range()) {
if (loose_edges.is_loose_bits[i]) {

View File

@ -202,7 +202,7 @@ void load_plydata(PlyData &plyData, Depsgraph *depsgraph, const PLYExportParams
}
/* Edges */
const bke::LooseGeomCache &loose_edges = mesh->loose_edges();
const bke::LooseEdgeCache &loose_edges = mesh->loose_edges();
if (loose_edges.count > 0) {
Span<MEdge> edges = mesh->edges();
for (int i = 0; i < edges.size(); ++i) {

View File

@ -413,7 +413,7 @@ void OBJWriter::write_edges_indices(FormatHandler &fh,
const OBJMesh &obj_mesh_data) const
{
const Mesh &mesh = *obj_mesh_data.get_mesh();
const bke::LooseGeomCache &loose_edges = mesh.loose_edges();
const bke::LooseEdgeCache &loose_edges = mesh.loose_edges();
if (loose_edges.count == 0) {
return;
}

View File

@ -26,7 +26,7 @@ namespace bke {
struct MeshRuntime;
class AttributeAccessor;
class MutableAttributeAccessor;
struct LooseGeomCache;
struct LooseEdgeCache;
} // namespace bke
} // namespace blender
using MeshRuntimeHandle = blender::bke::MeshRuntime;
@ -284,8 +284,8 @@ typedef struct Mesh {
/**
* Cached information about loose edges, calculated lazily when necessary.
*/
const blender::bke::LooseGeomCache &loose_edges() const;
const blender::bke::LooseGeomCache &loose_verts() const;
const blender::bke::LooseEdgeCache &loose_edges() const;
const blender::bke::LooseVertCache &loose_verts() const;
/**
* Explicitly set the cached number of loose edges to zero. This can improve performance
* later on, because finding loose edges lazily can be skipped entirely.