23#ifndef VCL_ALGORITHMS_MESH_POINT_SAMPLING_H
24#define VCL_ALGORITHMS_MESH_POINT_SAMPLING_H
26#include <vclib/algorithms/mesh/shuffle.h>
27#include <vclib/algorithms/mesh/stat.h>
29#include <vclib/mesh.h>
30#include <vclib/space/complex.h>
72template<MeshConcept MeshType>
78 using VertexType = MeshType::VertexType;
79 using PointType = VertexType::PositionType;
93 for (
const VertexType& v :
m.vertices()) {
120template<MeshConcept MeshType>
150template<FaceMeshConcept MeshType>
156 using PointType = MeshType::VertexType::PositionType;
157 using FaceType = MeshType::FaceType;
169 for (
const FaceType& f :
m.faces()) {
198template<FaceMeshConcept MeshType>
224template<MeshConcept MeshType>
230 std::optional<uint>
seed = std::nullopt)
232 using PointType = MeshType::VertexType::PositionType;
247 std::uniform_int_distribution<uint> dist(0,
m.vertexContainerSize() - 1);
251 std::vector<bool> visited(
m.vertexContainerSize(),
false);
256 if (!
m.vertex(
vi).deleted() && !visited[
vi] &&
285template<MeshConcept MeshType>
290 std::optional<uint>
seed = std::nullopt)
318template<FaceMeshConcept MeshType>
324 std::optional<uint>
seed = std::nullopt)
326 using PointType = MeshType::VertexType::PositionType;
341 std::uniform_int_distribution<uint> dist(0,
m.faceContainerSize() - 1);
345 std::vector<bool> visited(
m.faceContainerSize(),
false);
350 if (!
m.face(
fi).deleted() && !visited[
fi] &&
382template<FaceMeshConcept MeshType>
387 std::optional<uint>
seed = std::nullopt)
417template<MeshConcept MeshType,
typename ScalarType>
420 const std::vector<ScalarType>&
weights,
423 std::optional<uint>
seed = std::nullopt)
425 using PointType = MeshType::VertexType::PositionType;
436 std::discrete_distribution<> dist(std::begin(
weights), std::end(
weights));
440 std::vector<bool> visited(
m.vertexContainerSize(),
false);
445 if (
vi <
m.vertexContainerSize() && !
m.vertex(
vi).deleted() &&
478template<MeshConcept MeshType,
typename ScalarType>
481 const std::vector<ScalarType>&
weights,
483 std::optional<uint>
seed = std::nullopt)
514template<FaceMeshConcept MeshType,
typename ScalarType>
517 const std::vector<ScalarType>&
weights,
520 std::optional<uint>
seed = std::nullopt)
522 using PointType = MeshType::VertexType::PositionType;
535 std::discrete_distribution<> dist(std::begin(
weights), std::end(
weights));
539 std::vector<bool> visited(
m.faceContainerSize(),
false);
544 if (
fi <
m.faceContainerSize() && !
m.face(
fi).deleted() &&
578template<FaceMeshConcept MeshType,
typename ScalarType>
581 const std::vector<ScalarType>&
weights,
583 std::optional<uint>
seed = std::nullopt)
602template<MeshConcept MeshType>
606 std::optional<uint>
seed = std::nullopt)
608 requirePerVertexQuality(
m);
610 using VertexType = MeshType::VertexType;
611 using QualityType = VertexType::QualityType;
613 std::vector<QualityType>
weights;
614 weights.resize(
m.vertexContainerSize(), 0);
615 for (
const VertexType& v :
m.vertices()) {
635template<FaceMeshConcept MeshType>
639 std::optional<uint>
seed = std::nullopt)
643 using FaceType = MeshType::FaceType;
644 using QualityType = FaceType::QualityType;
646 std::vector<QualityType>
weights;
647 weights.resize(
m.faceContainerSize(), 0);
648 for (
const FaceType& f :
m.faces()) {
668template<FaceMeshConcept MeshType>
672 std::optional<uint>
seed = std::nullopt)
674 using VertexType = MeshType::VertexType;
675 using ScalarType = VertexType::ScalarType;
676 using FaceType = MeshType::FaceType;
678 std::vector<ScalarType>
weights(
m.vertexContainerSize(), 0);
679 std::vector<uint> cnt(
m.vertexContainerSize(), 0);
683 for (
const FaceType& f :
m.faces()) {
685 for (
const VertexType* v : f.vertices()) {
713template<FaceMeshConcept MeshType>
717 std::optional<uint>
seed = std::nullopt)
719 using FaceType = MeshType::FaceType;
721 std::vector<double>
weights(
m.faceContainerSize());
723 for (
const FaceType& f :
m.faces()) {
749template<FaceMeshConcept MeshType>
754 std::optional<uint>
seed = std::nullopt)
756 using VertexType = MeshType::VertexType;
757 using PointType = VertexType::PositionType;
758 using ScalarType = PointType::ScalarType;
759 using FaceType = MeshType::FaceType;
760 using Interval = std::pair<ScalarType, const FaceType*>;
770 std::uniform_real_distribution<ScalarType> dist(0, 1);
774 std::vector<Interval>
intervals(
m.faceNumber());
777 for (
const FaceType& f :
m.faces()) {
790 typename std::vector<Interval>::iterator
it = std::lower_bound(
793 std::make_pair(
val,
nullptr),
799 it->second->vertexNumber(),
gen));
822template<FaceMeshConcept MeshType>
826 std::optional<uint>
seed = std::nullopt)
832template<FaceMeshConcept MeshType>
833auto stratifiedMontecarloPointSampling(
836 std::optional<uint> seed = std::nullopt)
838 using FaceType = MeshType::FaceType;
839 using PointType = MeshType::VertexType::PositionType;
840 using ScalarType = PointType::ScalarType;
842 PointSampler<PointType> ps;
846 double area = surfaceArea(m);
847 double samplePerAreaUnit = nSamples / area;
849 double floatSampleNum = 0.0;
851 for (
const FaceType& f : m.faces()) {
854 floatSampleNum +=
faceArea(f) * samplePerAreaUnit;
855 int faceSampleNum = (int) floatSampleNum;
857 for (
int i = 0; i < faceSampleNum; i++)
860 randomPolygonBarycentricCoordinate<ScalarType>(
861 f.vertexNumber(), gen));
862 floatSampleNum -= (double) faceSampleNum;
891template<FaceMeshConcept MeshType>
895 std::optional<uint>
seed = std::nullopt)
897 using FaceType = MeshType::FaceType;
898 using PointType = MeshType::VertexType::PositionType;
899 using ScalarType = PointType::ScalarType;
905 ScalarType area = surfaceArea(
m);
908 for (
const FaceType& f :
m.faces()) {
917 f.vertexNumber(),
gen));
923template<FaceMeshConcept MeshType,
typename ScalarType>
924auto vertexWeightedMontecarloPointSampling(
926 const std::vector<ScalarType>& weights,
929 std::optional<uint> seed = std::nullopt)
931 using PointType = MeshType::VertexType::PositionType;
932 using FaceType = MeshType::FaceType;
935 auto weightedArea = [](
const FaceType& f,
937 const std::vector<ScalarType>& r) -> ScalarType {
938 ScalarType averageQ = 0;
939 for (uint i = 0; i < f.vertexNumber(); ++i)
940 averageQ += r[m.index(f.vertex(i))];
942 averageQ /= f.vertexNumber();
943 return averageQ * averageQ *
faceArea(f);
946 PointSampler<PointType> ps;
950 std::vector<ScalarType> radius =
951 vertexRadiusFromWeights(m, weights, 1.0, variance,
true);
953 ScalarType wArea = 0;
954 for (
const FaceType& f : m.
faces())
955 wArea += weightedArea(f, m, radius);
957 ScalarType samplePerAreaUnit = nSamples / wArea;
959 double floatSampleNum = 0.0;
960 for (
const FaceType& f : m.
faces()) {
963 floatSampleNum += weightedArea(f, m, radius) * samplePerAreaUnit;
964 uint faceSampleNum = (uint) floatSampleNum;
967 for (uint i = 0; i < faceSampleNum; i++)
970 randomPolygonBarycentricCoordinate<ScalarType>(
971 f.vertexNumber(), gen));
973 floatSampleNum -= (double) faceSampleNum;
979template<FaceMeshConcept MeshType>
980auto vertexQualityWeightedMontecarloPointSampling(
984 std::optional<uint> seed = std::nullopt)
986 requirePerVertexQuality(m);
988 using VertexType = MeshType::VertexType;
989 using QualityType = VertexType::QualityType;
991 std::vector<QualityType> weights;
992 weights.resize(m.vertexContainerSize(), 0);
993 for (
const VertexType& v : m.
vertices()) {
994 weights[m.index(v)] = v.quality();
997 return vertexWeightedMontecarloPointSampling(
998 m, weights, nSamples, variance, seed);
A class representing a box in N-dimensional space.
Definition box.h:46
void add(const PointT &p)
Adds the given point to the current box, expanding this box in order to contain also the values of th...
Definition box.h:385
PointT size() const
Computes the size of the box.
Definition box.h:267
int poissonRandomNumber(double lambda, std::mt19937 &gen)
algorithm poisson random number (Knuth): init: Let L ← e^−λ, k ← 0 and p ← 1. do: k ← k + 1....
Definition random.h:120
std::mt19937 randomGenerator(std::optional< uint > seed=std::nullopt)
Creates a random number generator with an optional seed.
Definition random.h:45
auto faceArea(const FaceType &f)
Computes the area of a face. Works both for triangle and polygonal faces, and it is optimized in case...
Definition geometry.h:108
void requirePerFaceQuality(const MeshType &m)
This function asserts that a Mesh has a FaceContainer, the Face has a Quality Component,...
Definition face_requirements.h:1250
auto vertexWeightedPointSampling(const MeshType &m, const std::vector< ScalarType > &weights, uint nSamples, std::vector< uint > &birthVertices, std::optional< uint > seed=std::nullopt)
Samples the vertices in a weighted way, using the per vertex weights given as input....
Definition point_sampling.h:418
auto vertexUniformPointSampling(const MeshType &m, uint nSamples, std::vector< uint > &birthVertices, bool onlySelected=false, std::optional< uint > seed=std::nullopt)
Returns a PointSampler object that contains the given number of samples taken from the vertices of th...
Definition point_sampling.h:225
auto faceWeightedPointSampling(const MeshType &m, const std::vector< ScalarType > &weights, uint nSamples, std::vector< uint > &birthFaces, std::optional< uint > seed=std::nullopt)
Returns a PointSampler object that contains the given number of samples taken from the faces of the g...
Definition point_sampling.h:515
auto faceAreaWeightedPointSampling(const MeshType &m, uint nSamples, std::optional< uint > seed=std::nullopt)
Samples the faces in a weighted way, using the per face area. Each face has a probability of being ch...
Definition point_sampling.h:714
auto montecarloPoissonPointSampling(const MeshType &m, uint nSamples, std::optional< uint > seed=std::nullopt)
This function compute montecarlo distribution with an approximate number of samples exploiting the po...
Definition point_sampling.h:892
auto montecarloPointSampling(const MeshType &m, uint nSamples, std::vector< uint > &birthFaces, std::optional< uint > seed=std::nullopt)
Computes a montecarlo distribution with an exact number of samples. It works by generating a sequence...
Definition point_sampling.h:750
auto vertexAreaWeightedPointSampling(const MeshType &m, uint nSamples, std::optional< uint > seed=std::nullopt)
Samples the vertices in a weighted way, using the area. Each vertex has a probability of being chosen...
Definition point_sampling.h:669
auto faceQualityWeightedPointSampling(const MeshType &m, uint nSamples, std::optional< uint > seed=std::nullopt)
Samples the faces in a weighted way, using the per face Quality component. Each face has a probabilit...
Definition point_sampling.h:636
auto vertexQualityWeightedPointSampling(const MeshType &m, uint nSamples, std::optional< uint > seed=std::nullopt)
Samples the vertices in a weighted way, using the per vertex Quality component. Each vertex has a pro...
Definition point_sampling.h:603
auto faceUniformPointSampling(const MeshType &m, uint nSamples, std::vector< uint > &birthFaces, bool onlySelected=false, std::optional< uint > seed=std::nullopt)
Returns a PointSampler object that contains the given number of samples taken from the faces of the g...
Definition point_sampling.h:319
auto allFacesPointSampling(const MeshType &m, std::vector< uint > &birthFaces, bool onlySelected=false)
Returns a PointSampler object that contains all the faces contained in the given mesh.
Definition point_sampling.h:151
auto allVerticesPointSampling(const MeshType &m, std::vector< uint > &birthVertices, bool onlySelected=false)
Returns a PointSampler object that contains all the vertices contained in the given mesh.
Definition point_sampling.h:73
constexpr detail::FacesView faces
A view that allows to iterate overt the Face elements of an object.
Definition face.h:84
constexpr detail::VerticesView vertices
A view that allows to iterate over the Vertex elements of an object.
Definition vertex.h:92