Added TrivialPointerSampler to sample a mesh returning pointers to the chosen vertexes.
Added another poisson pruning wrapper to make even easier to choose a subset of vertexes from a mesh with good distribution.
This commit is contained in:
parent
03206b6bc4
commit
4be7b59a80
|
@ -115,8 +115,28 @@ public:
|
||||||
}
|
}
|
||||||
}; // end class TrivialSampler
|
}; // end class TrivialSampler
|
||||||
|
|
||||||
|
template <class MeshType>
|
||||||
|
class TrivialPointerSampler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef typename MeshType::CoordType CoordType;
|
||||||
|
typedef typename MeshType::VertexType VertexType;
|
||||||
|
typedef typename MeshType::FaceType FaceType;
|
||||||
|
|
||||||
|
TrivialPointerSampler() {}
|
||||||
|
~TrivialPointerSampler() {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
std::vector<VertexType *> sampleVec;
|
||||||
|
|
||||||
|
void AddVert(const VertexType &p)
|
||||||
|
{
|
||||||
|
sampleVec->push_back(&p);
|
||||||
|
}
|
||||||
|
// This sampler should be used only for getting vertex pointers. Meaningless in other case.
|
||||||
|
void AddFace(const FaceType &, const CoordType &) { assert(0); }
|
||||||
|
void AddTextureSample(const FaceType &, const CoordType &, const Point2i &, float ) { assert(0); }
|
||||||
|
}; // end class TrivialSampler
|
||||||
|
|
||||||
|
|
||||||
template <class MeshType>
|
template <class MeshType>
|
||||||
|
@ -1381,6 +1401,8 @@ static void InitSpatialHashTable(MetroMesh &montecarloMesh, MontecarloSHT &monte
|
||||||
static void PoissonDiskPruning(VertexSampler &ps, MetroMesh &montecarloMesh,
|
static void PoissonDiskPruning(VertexSampler &ps, MetroMesh &montecarloMesh,
|
||||||
ScalarType diskRadius, const struct PoissonDiskParam pp=PoissonDiskParam())
|
ScalarType diskRadius, const struct PoissonDiskParam pp=PoissonDiskParam())
|
||||||
{
|
{
|
||||||
|
if(pp.adaptiveRadiusFlag)
|
||||||
|
tri::RequirePerVertexQuality(montecarloMesh);
|
||||||
int t0 = clock();
|
int t0 = clock();
|
||||||
// spatial index of montecarlo samples - used to choose a new sample to insert
|
// spatial index of montecarlo samples - used to choose a new sample to insert
|
||||||
MontecarloSHT montecarloSHT;
|
MontecarloSHT montecarloSHT;
|
||||||
|
@ -1733,15 +1755,74 @@ void PoissonSampling(MeshType &m, // the mesh that has to be sampled
|
||||||
template <class MeshType>
|
template <class MeshType>
|
||||||
void PoissonPruning(MeshType &m, // the mesh that has to be pruned
|
void PoissonPruning(MeshType &m, // the mesh that has to be pruned
|
||||||
std::vector<Point3f> &poissonSamples, // the vector that will contain the chosen set of points
|
std::vector<Point3f> &poissonSamples, // the vector that will contain the chosen set of points
|
||||||
float & radius)
|
float & radius, int sampleNum=0)
|
||||||
{
|
{
|
||||||
typedef tri::TrivialSampler<MeshType> BaseSampler;
|
typedef tri::TrivialSampler<MeshType> BaseSampler;
|
||||||
typename tri::SurfaceSampling<MeshType, BaseSampler>::PoissonDiskParam pp;
|
typename tri::SurfaceSampling<MeshType, BaseSampler>::PoissonDiskParam pp;
|
||||||
typename tri::SurfaceSampling<MeshType, BaseSampler>::PoissonDiskParam::Stat stat;
|
if(sampleNum>0 && radius==0)
|
||||||
pp.pds = &stat;
|
radius = tri::SurfaceSampling<MeshType,BaseSampler>::ComputePoissonDiskRadius(m,sampleNum);
|
||||||
tri::UpdateBounding<MeshType>::Box(m);
|
tri::UpdateBounding<MeshType>::Box(m);
|
||||||
BaseSampler pdSampler(poissonSamples);
|
BaseSampler pdSampler(poissonSamples);
|
||||||
tri::SurfaceSampling<MeshType,BaseSampler>::PoissonDiskPruning(pdSampler, m, radius,pp);
|
tri::SurfaceSampling<MeshType,BaseSampler>::PoissonDiskPruning(pdSampler, m, radius,pp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// \brief Very simple wrapping for the Poisson Disk Pruning
|
||||||
|
///
|
||||||
|
/// This function simply takes a mesh and a radius and returns a vector of points
|
||||||
|
//
|
||||||
|
template <class MeshType>
|
||||||
|
void PoissonPruning(MeshType &m, // the mesh that has to be pruned
|
||||||
|
std::vector<typename MeshType::VertexPointer> &poissonSamples, // the vector that will contain the chosen set of points
|
||||||
|
float & radius, int sampleNum=0)
|
||||||
|
{
|
||||||
|
typedef tri::TrivialPointerSampler<MeshType> BaseSampler;
|
||||||
|
typename tri::SurfaceSampling<MeshType, BaseSampler>::PoissonDiskParam pp;
|
||||||
|
if(sampleNum>0 && radius==0)
|
||||||
|
radius = tri::SurfaceSampling<MeshType,BaseSampler>::ComputePoissonDiskRadius(m,sampleNum);
|
||||||
|
|
||||||
|
tri::UpdateBounding<MeshType>::Box(m);
|
||||||
|
BaseSampler pdSampler;
|
||||||
|
tri::SurfaceSampling<MeshType,BaseSampler>::PoissonDiskPruning(pdSampler, m, radius,pp);
|
||||||
|
std::swap(pdSampler.sampleVec,poissonSamples);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Very simple wrapping for the Exact Poisson Disk Pruning
|
||||||
|
///
|
||||||
|
/// This function simply takes a mesh and an expected number of points and returns
|
||||||
|
/// vector of points. It performs multiple attempts with varius radii to correctly get the expected number of samples.
|
||||||
|
/// It is obviously much slower than the other versions...
|
||||||
|
|
||||||
|
|
||||||
|
template <class MeshType>
|
||||||
|
void PoissonPruningExact(MeshType &m, // the mesh that has to be pruned
|
||||||
|
std::vector<Point3f> &poissonSamples, // the vector that will contain the chosen set of points
|
||||||
|
float & radius,
|
||||||
|
int sampleNum,
|
||||||
|
float tolerance=0.04,
|
||||||
|
int maxIter=20)
|
||||||
|
{
|
||||||
|
int sampleNumMin = int(float(sampleNum)*(1.0f-tolerance));
|
||||||
|
int sampleNumMax = int(float(sampleNum)*(1.0f+tolerance));
|
||||||
|
float RadiusRangeMin = m.bbox.Diag()/100.0;
|
||||||
|
float RadiusRangeMax = m.bbox.Diag();
|
||||||
|
std::vector<Point3f> poissonSamplesTmp;
|
||||||
|
float curRadius;
|
||||||
|
int iterCnt=0;
|
||||||
|
while(iterCnt<maxIter &&
|
||||||
|
(poissonSamplesTmp.size() < sampleNumMin || poissonSamplesTmp.size() > sampleNumMax) )
|
||||||
|
{
|
||||||
|
curRadius=(RadiusRangeMax+RadiusRangeMin)/2.0f;
|
||||||
|
PoissonPruning(m,poissonSamplesTmp,curRadius);
|
||||||
|
//qDebug("(%f %f) Cur Radius %f -> %i sample instead of %i",RadiusRangeMin,RadiusRangeMax,curRadius,poissonSamplesTmp.size(),sampleNum);
|
||||||
|
if(poissonSamplesTmp.size() > sampleNum)
|
||||||
|
RadiusRangeMin = curRadius;
|
||||||
|
if(poissonSamplesTmp.size() < sampleNum)
|
||||||
|
RadiusRangeMax = curRadius;
|
||||||
|
}
|
||||||
|
|
||||||
|
swap(poissonSamples,poissonSamplesTmp);
|
||||||
|
radius = curRadius;
|
||||||
}
|
}
|
||||||
} // end namespace tri
|
} // end namespace tri
|
||||||
} // end namespace vcg
|
} // end namespace vcg
|
||||||
|
|
Loading…
Reference in New Issue