This implements a new internal data structure for reverse uv sampling. Being better than the previous one was not particularly hard, because it was never really optimized and used a very simple approach. I found the new implementation to be about 10-20x faster in my tests. Simon was able to reproduce an comparable speedups in production files. The speed-up is mainly achieved by a better memory layout and better multi-threading during construction. The lookup performance is mostly the same as before. Like the old data structure, the new one also splits the uv space into uniformly sized cells. The size of the cells is based on the number of triangles. Then it sorts all triangles into the rows that they touch. Finally, it creates a flat array for each row that contains the triangle indices contained in each cell. There are still ways to optimize this further, but for now this is a good improvement already. Pull Request: https://projects.blender.org/blender/blender/pulls/118772
51 lines
1.0 KiB
C++
51 lines
1.0 KiB
C++
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
#pragma once
|
|
|
|
#include <optional>
|
|
|
|
#include "BLI_math_vector_types.hh"
|
|
#include "BLI_multi_value_map.hh"
|
|
#include "BLI_span.hh"
|
|
|
|
namespace blender::geometry {
|
|
|
|
/**
|
|
* Can find the polygon/triangle that maps to a specific uv coordinate.
|
|
*
|
|
* \note this uses a trivial implementation currently that has to be replaced.
|
|
*/
|
|
class ReverseUVSampler {
|
|
public:
|
|
struct LookupGrid;
|
|
|
|
private:
|
|
Span<float2> uv_map_;
|
|
Span<int3> corner_tris_;
|
|
int resolution_;
|
|
std::unique_ptr<LookupGrid> lookup_grid_;
|
|
|
|
public:
|
|
ReverseUVSampler(Span<float2> uv_map, Span<int3> corner_tris);
|
|
~ReverseUVSampler();
|
|
|
|
enum class ResultType {
|
|
None,
|
|
Ok,
|
|
Multiple,
|
|
};
|
|
|
|
struct Result {
|
|
ResultType type = ResultType::None;
|
|
int tri_index = -1;
|
|
float3 bary_weights;
|
|
};
|
|
|
|
Result sample(const float2 &query_uv) const;
|
|
void sample_many(Span<float2> query_uvs, MutableSpan<Result> r_results) const;
|
|
};
|
|
|
|
} // namespace blender::geometry
|