Mesh: Cache loose vertices #105567
|
@ -176,8 +176,8 @@ struct MeshRuntime {
|
|||
* unchanged topology. Accessed with #Mesh::loose_edges()/loose_verts().
|
||||
*/
|
||||
SharedCache<LooseEdgeCache> loose_edges_cache;
|
||||
SharedCache<LooseVertCache> loose_verts_edge_cache;
|
||||
SharedCache<LooseVertCache> loose_verts_face_cache;
|
||||
SharedCache<LooseVertCache> loose_verts_no_edge_cache;
|
||||
SharedCache<LooseVertCache> loose_verts_no_face_cache;
|
||||
|
||||
/**
|
||||
* A bit vector the size of the number of vertices, set to true for the center vertices of
|
||||
|
|
|
@ -1213,7 +1213,7 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data,
|
|||
|
||||
switch (bvh_cache_type) {
|
||||
case BVHTREE_FROM_LOOSEVERTS: {
|
||||
const blender::bke::LooseVertCache &loose_verts = mesh->loose_verts_edge();
|
||||
const blender::bke::LooseVertCache &loose_verts = mesh->loose_verts_no_edge();
|
||||
data->tree = bvhtree_from_mesh_verts_create_tree(0.0f,
|
||||
tree_type,
|
||||
6,
|
||||
|
|
|
@ -767,7 +767,7 @@ Mesh *curve_to_mesh_sweep(const CurvesGeometry &main,
|
|||
|
||||
if (!offsets.any_single_point_curve) {
|
||||
/* If there are no single point curves, every curve combination will always have faces. */
|
||||
mesh->loose_verts_tag_none();
|
||||
mesh->tag_loose_verts_none();
|
||||
mesh->loose_edges_tag_none();
|
||||
}
|
||||
|
||||
|
|
|
@ -200,7 +200,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::LooseVertCache &loose_verts = mesh.loose_verts_face();
|
||||
const bke::LooseVertCache &loose_verts = mesh.loose_verts_no_face();
|
||||
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) {
|
||||
|
@ -753,12 +753,12 @@ static bool can_simple_adapt_for_single(const Mesh &mesh,
|
|||
return true;
|
||||
case ATTR_DOMAIN_EDGE:
|
||||
if (to_domain == ATTR_DOMAIN_POINT) {
|
||||
return mesh.loose_verts_edge().count == 0;
|
||||
return mesh.loose_verts_no_edge().count == 0;
|
||||
}
|
||||
return true;
|
||||
case ATTR_DOMAIN_FACE:
|
||||
if (to_domain == ATTR_DOMAIN_POINT) {
|
||||
return mesh.loose_verts_face().count == 0;
|
||||
return mesh.loose_verts_no_face().count == 0;
|
||||
}
|
||||
if (to_domain == ATTR_DOMAIN_EDGE) {
|
||||
return mesh.loose_edges().count == 0;
|
||||
|
@ -766,7 +766,7 @@ static bool can_simple_adapt_for_single(const Mesh &mesh,
|
|||
return true;
|
||||
case ATTR_DOMAIN_CORNER:
|
||||
if (to_domain == ATTR_DOMAIN_POINT) {
|
||||
return mesh.loose_verts_face().count == 0;
|
||||
return mesh.loose_verts_no_face().count == 0;
|
||||
}
|
||||
if (to_domain == ATTR_DOMAIN_EDGE) {
|
||||
return mesh.loose_edges().count == 0;
|
||||
|
|
|
@ -130,8 +130,8 @@ static void mesh_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int
|
|||
* when the source is persistent and edits to the destination mesh don't affect the caches.
|
||||
* Caches will be "un-shared" as necessary later on. */
|
||||
mesh_dst->runtime->bounds_cache = mesh_src->runtime->bounds_cache;
|
||||
mesh_dst->runtime->loose_verts_edge_cache = mesh_src->runtime->loose_verts_edge_cache;
|
||||
mesh_dst->runtime->loose_verts_face_cache = mesh_src->runtime->loose_verts_face_cache;
|
||||
mesh_dst->runtime->loose_verts_no_edge_cache = mesh_src->runtime->loose_verts_no_edge_cache;
|
||||
mesh_dst->runtime->loose_verts_no_face_cache = mesh_src->runtime->loose_verts_no_face_cache;
|
||||
mesh_dst->runtime->loose_edges_cache = mesh_src->runtime->loose_edges_cache;
|
||||
mesh_dst->runtime->looptris_cache = mesh_src->runtime->looptris_cache;
|
||||
|
||||
|
|
|
@ -108,10 +108,10 @@ MeshRuntime::~MeshRuntime()
|
|||
|
||||
} // namespace blender::bke
|
||||
|
||||
const blender::bke::LooseVertCache &Mesh::loose_verts_edge() const
|
||||
const blender::bke::LooseVertCache &Mesh::loose_verts_no_edge() const
|
||||
{
|
||||
using namespace blender::bke;
|
||||
this->runtime->loose_verts_edge_cache.ensure([&](LooseVertCache &r_data) {
|
||||
this->runtime->loose_verts_no_edge_cache.ensure([&](LooseVertCache &r_data) {
|
||||
blender::BitVector<> &loose_verts = r_data.is_loose_bits;
|
||||
loose_verts.resize(0);
|
||||
loose_verts.resize(this->totvert, true);
|
||||
|
@ -129,13 +129,13 @@ const blender::bke::LooseVertCache &Mesh::loose_verts_edge() const
|
|||
r_data.count = count;
|
||||
});
|
||||
|
||||
return this->runtime->loose_verts_edge_cache.data();
|
||||
return this->runtime->loose_verts_no_edge_cache.data();
|
||||
}
|
||||
|
||||
const blender::bke::LooseVertCache &Mesh::loose_verts_face() const
|
||||
const blender::bke::LooseVertCache &Mesh::loose_verts_no_face() const
|
||||
{
|
||||
using namespace blender::bke;
|
||||
this->runtime->loose_verts_face_cache.ensure([&](LooseVertCache &r_data) {
|
||||
this->runtime->loose_verts_no_face_cache.ensure([&](LooseVertCache &r_data) {
|
||||
blender::BitVector<> &loose_verts = r_data.is_loose_bits;
|
||||
loose_verts.resize(0);
|
||||
loose_verts.resize(this->totvert, true);
|
||||
|
@ -153,7 +153,7 @@ const blender::bke::LooseVertCache &Mesh::loose_verts_face() const
|
|||
r_data.count = count;
|
||||
});
|
||||
|
||||
return this->runtime->loose_verts_face_cache.data();
|
||||
return this->runtime->loose_verts_no_face_cache.data();
|
||||
}
|
||||
|
||||
const blender::bke::LooseEdgeCache &Mesh::loose_edges() const
|
||||
|
@ -180,26 +180,26 @@ const blender::bke::LooseEdgeCache &Mesh::loose_edges() const
|
|||
return this->runtime->loose_edges_cache.data();
|
||||
}
|
||||
|
||||
void Mesh::loose_verts_edge_tag_none() const
|
||||
void Mesh::tag_loose_verts_no_edge_none() const
|
||||
{
|
||||
using namespace blender::bke;
|
||||
this->runtime->loose_verts_edge_cache.ensure([&](LooseVertCache &r_data) {
|
||||
this->runtime->loose_verts_no_edge_cache.ensure([&](LooseVertCache &r_data) {
|
||||
r_data.is_loose_bits.clear_and_shrink();
|
||||
r_data.count = 0;
|
||||
});
|
||||
}
|
||||
void Mesh::loose_verts_face_tag_none() const
|
||||
void Mesh::tag_loose_verts_no_face_none() const
|
||||
{
|
||||
using namespace blender::bke;
|
||||
this->runtime->loose_verts_face_cache.ensure([&](LooseVertCache &r_data) {
|
||||
this->runtime->loose_verts_no_face_cache.ensure([&](LooseVertCache &r_data) {
|
||||
r_data.is_loose_bits.clear_and_shrink();
|
||||
r_data.count = 0;
|
||||
});
|
||||
}
|
||||
void Mesh::loose_verts_tag_none() const
|
||||
void Mesh::tag_loose_verts_none() const
|
||||
{
|
||||
this->loose_verts_edge_tag_none();
|
||||
this->loose_verts_face_tag_none();
|
||||
this->tag_loose_verts_no_edge_none();
|
||||
this->tag_loose_verts_no_face_none();
|
||||
}
|
||||
|
||||
void Mesh::loose_edges_tag_none() const
|
||||
|
@ -289,8 +289,8 @@ void BKE_mesh_runtime_clear_geometry(Mesh *mesh)
|
|||
free_subdiv_ccg(*mesh->runtime);
|
||||
mesh->runtime->bounds_cache.tag_dirty();
|
||||
mesh->runtime->loose_edges_cache.tag_dirty();
|
||||
mesh->runtime->loose_verts_edge_cache.tag_dirty();
|
||||
mesh->runtime->loose_verts_face_cache.tag_dirty();
|
||||
mesh->runtime->loose_verts_no_edge_cache.tag_dirty();
|
||||
mesh->runtime->loose_verts_no_face_cache.tag_dirty();
|
||||
mesh->runtime->looptris_cache.tag_dirty();
|
||||
mesh->runtime->subsurf_face_dot_tags.clear_and_shrink();
|
||||
mesh->runtime->subsurf_optimal_display_edges.clear_and_shrink();
|
||||
|
@ -309,8 +309,8 @@ void BKE_mesh_tag_edges_split(struct Mesh *mesh)
|
|||
reset_normals(*mesh->runtime);
|
||||
free_subdiv_ccg(*mesh->runtime);
|
||||
mesh->runtime->loose_edges_cache.tag_dirty();
|
||||
mesh->runtime->loose_verts_edge_cache.tag_dirty();
|
||||
mesh->runtime->loose_verts_face_cache.tag_dirty();
|
||||
mesh->runtime->loose_verts_no_edge_cache.tag_dirty();
|
||||
mesh->runtime->loose_verts_no_face_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) {
|
||||
|
|
|
@ -354,7 +354,7 @@ static void initialize_manifold_indices(ConverterStorage *storage)
|
|||
{
|
||||
using namespace blender;
|
||||
const Mesh *mesh = storage->mesh;
|
||||
const bke::LooseVertCache &loose_verts = mesh->loose_verts_face();
|
||||
const bke::LooseVertCache &loose_verts = mesh->loose_verts_no_face();
|
||||
const bke::LooseEdgeCache &loose_edges = mesh->loose_edges();
|
||||
initialize_manifold_index_array(loose_verts.is_loose_bits,
|
||||
mesh->totvert,
|
||||
|
|
|
@ -46,7 +46,7 @@ static void mesh_render_data_loose_geom_mesh(const MeshRenderData *mr, MeshBuffe
|
|||
}
|
||||
}
|
||||
|
||||
const bke::LooseVertCache &loose_verts = mr->me->loose_verts_edge();
|
||||
const bke::LooseVertCache &loose_verts = mr->me->loose_verts_no_edge();
|
||||
if (loose_verts.count > 0) {
|
||||
cache->loose_geom.verts.reinitialize(loose_verts.count);
|
||||
|
||||
|
|
|
@ -417,7 +417,7 @@ Mesh *create_cuboid_mesh(const float3 &size,
|
|||
|
||||
const float3 bounds = size * 0.5f;
|
||||
mesh->bounds_set_eager({-bounds, bounds});
|
||||
mesh->loose_verts_tag_none();
|
||||
mesh->tag_loose_verts_none();
|
||||
|
||||
return mesh;
|
||||
}
|
||||
|
|
|
@ -951,13 +951,13 @@ static AllMeshesInfo preprocess_meshes(const GeometrySet &geometry_set,
|
|||
});
|
||||
info.no_loose_verts_edge_hint = std::all_of(
|
||||
info.order.begin(), info.order.end(), [](const Mesh *mesh) {
|
||||
return mesh->runtime->loose_verts_edge_cache.is_cached() &&
|
||||
mesh->loose_verts_edge().count == 0;
|
||||
return mesh->runtime->loose_verts_no_edge_cache.is_cached() &&
|
||||
mesh->loose_verts_no_edge().count == 0;
|
||||
});
|
||||
info.no_loose_verts_face_hint = std::all_of(
|
||||
info.order.begin(), info.order.end(), [](const Mesh *mesh) {
|
||||
return mesh->runtime->loose_verts_face_cache.is_cached() &&
|
||||
mesh->loose_verts_face().count == 0;
|
||||
return mesh->runtime->loose_verts_no_face_cache.is_cached() &&
|
||||
mesh->loose_verts_no_face().count == 0;
|
||||
});
|
||||
|
||||
return info;
|
||||
|
@ -1168,10 +1168,10 @@ static void execute_realize_mesh_tasks(const RealizeInstancesOptions &options,
|
|||
dst_mesh->loose_edges_tag_none();
|
||||
}
|
||||
if (all_meshes_info.no_loose_verts_edge_hint) {
|
||||
dst_mesh->loose_verts_edge_tag_none();
|
||||
dst_mesh->tag_loose_verts_no_edge_none();
|
||||
}
|
||||
if (all_meshes_info.no_loose_verts_face_hint) {
|
||||
dst_mesh->loose_verts_face_tag_none();
|
||||
dst_mesh->tag_loose_verts_no_face_none();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -306,11 +306,11 @@ typedef struct Mesh {
|
|||
/**
|
||||
* Cached information about vertices that aren't used by any edges.
|
||||
*/
|
||||
const blender::bke::LooseVertCache &loose_verts_edge() const;
|
||||
const blender::bke::LooseVertCache &loose_verts_no_edge() const;
|
||||
/**
|
||||
* Cached information about vertices that aren't used by faces (but may be used by loose edges).
|
||||
*/
|
||||
const blender::bke::LooseVertCache &loose_verts_face() const;
|
||||
const blender::bke::LooseVertCache &loose_verts_no_face() const;
|
||||
|
||||
/**
|
||||
* Explicitly set the cached number of loose edges to zero. This can improve performance
|
||||
|
@ -320,9 +320,9 @@ typedef struct Mesh {
|
|||
* cache dirty. If the mesh was changed first, the relevant dirty tags should be called first.
|
||||
|
||||
*/
|
||||
Jacques Lucke
commented
It feels a bit like these It feels a bit like these `tag` functions are redundant. Shouldn't `tag_no_loose_edges` and `tag_no_loose_verts` methods be enough?
Hans Goudey
commented
Generally they're used in similar situations, but not always. For example, the realize instances node:
Generally they're used in similar situations, but not always. For example, the realize instances node:
```
if (all_meshes_info.no_loose_verts_edge_hint) {
dst_mesh->loose_verts_edge_tag_none();
}
if (all_meshes_info.no_loose_verts_face_hint) {
dst_mesh->loose_verts_face_tag_none();
}
```
|
||||
void loose_edges_tag_none() const;
|
||||
void loose_verts_edge_tag_none() const;
|
||||
void loose_verts_face_tag_none() const;
|
||||
void loose_verts_tag_none() const;
|
||||
void tag_loose_verts_no_edge_none() const;
|
||||
void tag_loose_verts_no_face_none() const;
|
||||
void tag_loose_verts_none() const;
|
||||
|
||||
/**
|
||||
* Normal direction of polygons, defined by positions and the winding direction of face corners.
|
||||
|
|
|
@ -551,7 +551,7 @@ static void duplicate_faces(GeometrySet &geometry_set,
|
|||
}
|
||||
}
|
||||
|
||||
new_mesh->loose_verts_tag_none();
|
||||
new_mesh->tag_loose_verts_none();
|
||||
new_mesh->loose_edges_tag_none();
|
||||
|
||||
copy_face_attributes_without_id(edge_mapping,
|
||||
|
|
|
@ -154,7 +154,7 @@ static Mesh *create_circle_mesh(const float radius,
|
|||
std::iota(corner_verts.begin(), corner_verts.end(), 0);
|
||||
std::iota(corner_edges.begin(), corner_edges.end(), 0);
|
||||
|
||||
mesh->loose_verts_tag_none();
|
||||
mesh->tag_loose_verts_none();
|
||||
}
|
||||
else if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN) {
|
||||
for (const int i : poly_offsets.index_range()) {
|
||||
|
@ -171,7 +171,7 @@ static Mesh *create_circle_mesh(const float radius,
|
|||
corner_edges[3 * i + 2] = verts_num + i;
|
||||
}
|
||||
|
||||
mesh->loose_verts_edge_tag_none();
|
||||
mesh->tag_loose_verts_no_edge_none();
|
||||
}
|
||||
|
||||
mesh->bounds_set_eager(calculate_bounds_circle(radius, verts_num));
|
||||
|
|
|
@ -723,7 +723,7 @@ Mesh *create_cylinder_or_cone_mesh(const float radius_top,
|
|||
}
|
||||
calculate_selection_outputs(config, attribute_outputs, mesh->attributes_for_write());
|
||||
|
||||
mesh->loose_verts_tag_none();
|
||||
mesh->tag_loose_verts_none();
|
||||
mesh->loose_edges_tag_none();
|
||||
mesh->bounds_set_eager(calculate_bounds_cylinder(config));
|
||||
|
||||
|
|
|
@ -149,7 +149,7 @@ Mesh *create_grid_mesh(const int verts_x,
|
|||
calculate_uvs(mesh, positions, corner_verts, size_x, size_y, uv_map_id);
|
||||
}
|
||||
|
||||
mesh->loose_verts_tag_none();
|
||||
mesh->tag_loose_verts_none();
|
||||
mesh->loose_edges_tag_none();
|
||||
|
||||
const float3 bounds = float3(size_x * 0.5f, size_y * 0.5f, 0.0f);
|
||||
|
|
|
@ -333,7 +333,7 @@ static Mesh *create_uv_sphere_mesh(const float radius,
|
|||
}
|
||||
});
|
||||
|
||||
mesh->loose_verts_tag_none();
|
||||
mesh->tag_loose_verts_none();
|
||||
mesh->loose_edges_tag_none();
|
||||
mesh->bounds_set_eager(calculate_bounds_uv_sphere(radius, segments, rings));
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Why are these
const
? Aren't these function you should call after changing the topology when having non-const access to the mesh?BKE_mesh_tag_positions_changed
is non-const as well.They're const because setting them doesn't change the logical state of the mesh. Let's say you're doing a mostly unrelated calculation and discover that there are no loose vertices, these could be called to pass that information elsewhere without changing the mesh.
BKE_mesh_tag_positions_changed
is different, it means "I've changed the positions, the mesh is now different than it was".