BLI: Add utility to reverse index mask
This utility was already duplicated in two places and planned to be used more. While we should usually avoid creating arrays the size of the indexed array (rather than the size of the mask), sometimes it does seem to be the best option, and we're helped by the fact that most memory stays unintialized for a small mask (allocating but not writing to memory pages at all generally isn't too expensive). Pull Request: https://projects.blender.org/blender/blender/pulls/115491
This commit is contained in:
@@ -423,7 +423,7 @@ const IndexMask &get_static_index_mask_for_min_size(const int64_t min_size);
|
||||
std::ostream &operator<<(std::ostream &stream, const IndexMask &mask);
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Inline Utilities
|
||||
/** \name Utilities
|
||||
* \{ */
|
||||
|
||||
inline const std::array<int16_t, max_segment_size> &get_static_indices_array()
|
||||
@@ -439,6 +439,13 @@ inline void masked_fill(MutableSpan<T> data, const T &value, const IndexMask &ma
|
||||
mask.foreach_index_optimized<int64_t>([&](const int64_t i) { data[i] = value; });
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill masked indices of \a r_mask with the index of that item in the mask such that
|
||||
* `r_map[mask[i]] == i` for the whole mask. The size of `r_map` needs to be at least
|
||||
* `mask.min_array_size()`.
|
||||
*/
|
||||
template<typename T> void build_reverse_map(const IndexMask &mask, MutableSpan<T> r_map);
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name #RawMaskIterator Inline Methods
|
||||
* \{ */
|
||||
|
||||
@@ -20,6 +20,19 @@
|
||||
|
||||
namespace blender::index_mask {
|
||||
|
||||
template<typename T> void build_reverse_map(const IndexMask &mask, MutableSpan<T> r_map)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
/* Catch errors with asserts in debug builds. */
|
||||
r_map.fill(-1);
|
||||
#endif
|
||||
BLI_assert(r_map.size() >= mask.min_array_size());
|
||||
mask.foreach_index_optimized<T>(GrainSize(4096),
|
||||
[&](const T src, const T dst) { r_map[src] = dst; });
|
||||
}
|
||||
|
||||
template void build_reverse_map<int>(const IndexMask &mask, MutableSpan<int> r_map);
|
||||
|
||||
std::array<int16_t, max_segment_size> build_static_indices_array()
|
||||
{
|
||||
std::array<int16_t, max_segment_size> data;
|
||||
|
||||
@@ -17,15 +17,6 @@
|
||||
|
||||
namespace blender::geometry {
|
||||
|
||||
static void create_reverse_map(const IndexMask &mask, MutableSpan<int> r_map)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
r_map.fill(-1);
|
||||
#endif
|
||||
mask.foreach_index_optimized<int>(
|
||||
GrainSize(4096), [&](const int src_i, const int dst_i) { r_map[src_i] = dst_i; });
|
||||
}
|
||||
|
||||
static void remap_verts(const OffsetIndices<int> src_faces,
|
||||
const OffsetIndices<int> dst_faces,
|
||||
const int src_verts_num,
|
||||
@@ -38,7 +29,7 @@ static void remap_verts(const OffsetIndices<int> src_faces,
|
||||
MutableSpan<int> dst_corner_verts)
|
||||
{
|
||||
Array<int> map(src_verts_num);
|
||||
create_reverse_map(vert_mask, map);
|
||||
index_mask::build_reverse_map<int>(vert_mask, map);
|
||||
threading::parallel_invoke(
|
||||
vert_mask.size() > 1024,
|
||||
[&]() {
|
||||
@@ -67,7 +58,7 @@ static void remap_edges(const OffsetIndices<int> src_faces,
|
||||
MutableSpan<int> dst_corner_edges)
|
||||
{
|
||||
Array<int> map(src_edges_num);
|
||||
create_reverse_map(edge_mask, map);
|
||||
index_mask::build_reverse_map<int>(edge_mask, map);
|
||||
face_mask.foreach_index(GrainSize(512), [&](const int64_t src_i, const int64_t dst_i) {
|
||||
const IndexRange src_face = src_faces[src_i];
|
||||
const IndexRange dst_face = dst_faces[dst_i];
|
||||
|
||||
@@ -444,15 +444,6 @@ static void fill_quad_consistent_direction(const Span<int> other_face_verts,
|
||||
}
|
||||
}
|
||||
|
||||
static void create_reverse_map(const IndexMask &mask, MutableSpan<int> r_map)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
r_map.fill(-1);
|
||||
#endif
|
||||
mask.foreach_index_optimized<int>(
|
||||
GrainSize(4096), [&](const int src_i, const int dst_i) { r_map[src_i] = dst_i; });
|
||||
}
|
||||
|
||||
static GroupedSpan<int> build_vert_to_edge_map(const Span<int2> edges,
|
||||
const IndexMask &edge_mask,
|
||||
const int verts_num,
|
||||
@@ -596,7 +587,7 @@ static void extrude_mesh_edges(Mesh &mesh,
|
||||
|
||||
{
|
||||
Array<int> vert_to_new_vert(orig_vert_size);
|
||||
create_reverse_map(new_verts, vert_to_new_vert);
|
||||
index_mask::build_reverse_map<int>(new_verts, vert_to_new_vert);
|
||||
for (const int i : duplicate_edges.index_range()) {
|
||||
const int2 orig_edge = edges[edge_selection[i]];
|
||||
const int i_new_vert_1 = vert_to_new_vert[orig_edge[0]];
|
||||
|
||||
Reference in New Issue
Block a user