diff options
Diffstat (limited to 'source/blender/blenkernel/BKE_mesh_sample.hh')
-rw-r--r-- | source/blender/blenkernel/BKE_mesh_sample.hh | 105 |
1 files changed, 83 insertions, 22 deletions
diff --git a/source/blender/blenkernel/BKE_mesh_sample.hh b/source/blender/blenkernel/BKE_mesh_sample.hh index 37c2ad7d3cb..94dc52d5ec9 100644 --- a/source/blender/blenkernel/BKE_mesh_sample.hh +++ b/source/blender/blenkernel/BKE_mesh_sample.hh @@ -6,39 +6,42 @@ * \ingroup bke */ +#include "BLI_function_ref.hh" #include "BLI_generic_virtual_array.hh" #include "BLI_math_vec_types.hh" +#include "DNA_meshdata_types.h" + #include "BKE_attribute.h" struct Mesh; +struct BVHTreeFromMesh; -namespace blender::bke { -struct ReadAttributeLookup; -class OutputAttribute; -} // namespace blender::bke +namespace blender { +class RandomNumberGenerator; +} namespace blender::bke::mesh_surface_sample { void sample_point_attribute(const Mesh &mesh, Span<int> looptri_indices, Span<float3> bary_coords, - const GVArray &data_in, - const IndexMask mask, - GMutableSpan data_out); + const GVArray &src, + IndexMask mask, + GMutableSpan dst); void sample_corner_attribute(const Mesh &mesh, Span<int> looptri_indices, Span<float3> bary_coords, - const GVArray &data_in, - const IndexMask mask, - GMutableSpan data_out); + const GVArray &src, + IndexMask mask, + GMutableSpan dst); void sample_face_attribute(const Mesh &mesh, Span<int> looptri_indices, - const GVArray &data_in, - const IndexMask mask, - GMutableSpan data_out); + const GVArray &src, + IndexMask mask, + GMutableSpan dst); enum class eAttributeMapMode { INTERPOLATED, @@ -53,7 +56,6 @@ enum class eAttributeMapMode { * these are computed lazily when needed and re-used. */ class MeshAttributeInterpolator { - private: const Mesh *mesh_; const IndexMask mask_; const Span<float3> positions_; @@ -64,22 +66,81 @@ class MeshAttributeInterpolator { public: MeshAttributeInterpolator(const Mesh *mesh, - const IndexMask mask, - const Span<float3> positions, - const Span<int> looptri_indices); + IndexMask mask, + Span<float3> positions, + Span<int> looptri_indices); void sample_data(const GVArray &src, eAttrDomain domain, eAttributeMapMode mode, - const GMutableSpan dst); - - void sample_attribute(const ReadAttributeLookup &src_attribute, - OutputAttribute &dst_attribute, - eAttributeMapMode mode); + GMutableSpan dst); protected: Span<float3> ensure_barycentric_coords(); Span<float3> ensure_nearest_weights(); }; +/** + * Find randomly distributed points on the surface of a mesh within a 3D sphere. This does not + * sample an exact number of points because it comes with extra overhead to avoid bias that is only + * required in some cases. If an exact number of points is required, that has to be implemented at + * a higher level. + * + * \param approximate_density: Roughly the number of points per unit of area. + * \return The number of added points. + */ +int sample_surface_points_spherical(RandomNumberGenerator &rng, + const Mesh &mesh, + Span<int> looptri_indices_to_sample, + const float3 &sample_pos, + float sample_radius, + float approximate_density, + Vector<float3> &r_bary_coords, + Vector<int> &r_looptri_indices, + Vector<float3> &r_positions); + +/** + * Find randomly distributed points on the surface of a mesh within a circle that is projected on + * the mesh. This does not result in an exact number of points because that would come with extra + * overhead and is not always possible. If an exact number of points is required, that has to be + * implemented at a higher level. + * + * \param region_position_to_ray: Function that converts a 2D position into a 3D ray that is used + * to find positions on the mesh. + * \param mesh_bvhtree: BVH tree of the triangles in the mesh. Passed in so that it does not have + * to be retrieved again. + * \param tries_num: Number of 2d positions that are sampled. The maximum + * number of new samples. + * \return The number of added points. + */ +int sample_surface_points_projected( + RandomNumberGenerator &rng, + const Mesh &mesh, + BVHTreeFromMesh &mesh_bvhtree, + const float2 &sample_pos_re, + float sample_radius_re, + FunctionRef<void(const float2 &pos_re, float3 &r_start, float3 &r_end)> region_position_to_ray, + bool front_face_only, + int tries_num, + int max_points, + Vector<float3> &r_bary_coords, + Vector<int> &r_looptri_indices, + Vector<float3> &r_positions); + +float3 compute_bary_coord_in_triangle(Span<MVert> verts, + Span<MLoop> loops, + const MLoopTri &looptri, + const float3 &position); + +template<typename T> +inline T sample_corner_attrribute_with_bary_coords(const float3 &bary_weights, + const MLoopTri &looptri, + const Span<T> corner_attribute) +{ + return attribute_math::mix3(bary_weights, + corner_attribute[looptri.tri[0]], + corner_attribute[looptri.tri[1]], + corner_attribute[looptri.tri[2]]); +} + } // namespace blender::bke::mesh_surface_sample |