Added a default parameter to the sampling class and a few utility sampling classes for taking point on faces.

This commit is contained in:
Paolo Cignoni 2012-10-22 18:42:11 +00:00
parent c980267cd8
commit ecd88fcb28
1 changed files with 27 additions and 10 deletions

View File

@ -109,7 +109,7 @@ class TrivialSampler
} }
}; // end class TrivialSampler }; // end class TrivialSampler
template <class MetroMesh, class VertexSampler> template <class MetroMesh, class VertexSampler = TrivialSampler< MetroMesh> >
class SurfaceSampling class SurfaceSampling
{ {
typedef typename MetroMesh::CoordType CoordType; typedef typename MetroMesh::CoordType CoordType;
@ -149,6 +149,15 @@ static double RandomDouble01()
return SamplingRandomGenerator().generate01(); return SamplingRandomGenerator().generate01();
} }
static Point3f RandomPoint3fBall01()
{
while(1)
{
Point3f p=Point3f(0.5f-RandomDouble01(),0.5f-RandomDouble01(),0.5f-RandomDouble01());
if(SquaredNorm(p)<=0.25) return p*2.0f;
}
}
#define FAK_LEN 1024 #define FAK_LEN 1024
static double LnFac(int n) { static double LnFac(int n) {
// Tabled log factorial function. gives natural logarithm of n! // Tabled log factorial function. gives natural logarithm of n!
@ -460,7 +469,7 @@ static void EdgeUniform(MetroMesh & m, VertexSampler &ps,int sampleNum, bool sam
// Generate the barycentric coords of a random point over a single face, // Generate the barycentric coords of a random point over a single face,
// with a uniform distribution over the triangle. // with a uniform distribution over the triangle.
// It uses the parallelogram folding trick. // It uses the parallelogram folding trick.
static CoordType RandomBaricentric() static CoordType RandomBarycentric()
{ {
CoordType interp; CoordType interp;
interp[1] = RandomDouble01(); interp[1] = RandomDouble01();
@ -476,6 +485,14 @@ static CoordType RandomBaricentric()
return interp; return interp;
} }
// Given a triangle return a random point over it
static CoordType RandomPointInTriangle(const FaceType &f)
{
CoordType u = RandomBarycentric();
return f.cP(0)*u[0] + f.cP(1)*u[1] + f.cP(2)*u[2];
}
static void StratifiedMontecarlo(MetroMesh & m, VertexSampler &ps,int sampleNum) static void StratifiedMontecarlo(MetroMesh & m, VertexSampler &ps,int sampleNum)
{ {
ScalarType area = Stat<MetroMesh>::ComputeMeshArea(m); ScalarType area = Stat<MetroMesh>::ComputeMeshArea(m);
@ -493,7 +510,7 @@ static void StratifiedMontecarlo(MetroMesh & m, VertexSampler &ps,int sampleNum)
// for every sample p_i in T... // for every sample p_i in T...
for(int i=0; i < faceSampleNum; i++) for(int i=0; i < faceSampleNum; i++)
ps.AddFace(*fi,RandomBaricentric()); ps.AddFace(*fi,RandomBarycentric());
floatSampleNum -= (double) faceSampleNum; floatSampleNum -= (double) faceSampleNum;
} }
} }
@ -524,7 +541,7 @@ static void MontecarloPoisson(MetroMesh & m, VertexSampler &ps,int sampleNum)
// for every sample p_i in T... // for every sample p_i in T...
for(int i=0; i < faceSampleNum; i++) for(int i=0; i < faceSampleNum; i++)
ps.AddFace(*fi,RandomBaricentric()); ps.AddFace(*fi,RandomBarycentric());
// SampleNum -= (double) faceSampleNum; // SampleNum -= (double) faceSampleNum;
} }
} }
@ -560,7 +577,7 @@ static void Montecarlo(MetroMesh & m, VertexSampler &ps,int sampleNum)
assert(it != intervals.begin()); assert(it != intervals.begin());
assert( (*(it-1)).first <val ); assert( (*(it-1)).first <val );
assert( (*(it)).first >= val); assert( (*(it)).first >= val);
ps.AddFace( *(*it).second, RandomBaricentric() ); ps.AddFace( *(*it).second, RandomBarycentric() );
} }
} }
@ -595,7 +612,7 @@ static void WeightedMontecarlo(MetroMesh & m, VertexSampler &ps, int sampleNum)
// for every sample p_i in T... // for every sample p_i in T...
for(int i=0; i < faceSampleNum; i++) for(int i=0; i < faceSampleNum; i++)
ps.AddFace(*fi,RandomBaricentric()); ps.AddFace(*fi,RandomBarycentric());
floatSampleNum -= (double) faceSampleNum; floatSampleNum -= (double) faceSampleNum;
} }
@ -614,7 +631,7 @@ static int SingleFaceSubdivision(int sampleNum, const CoordType & v0, const Coor
CoordType SamplePoint; CoordType SamplePoint;
if(randSample) if(randSample)
{ {
CoordType rb=RandomBaricentric(); CoordType rb=RandomBarycentric();
SamplePoint=v0*rb[0]+v1*rb[1]+v2*rb[2]; SamplePoint=v0*rb[0]+v1*rb[1]+v2*rb[2];
} }
else SamplePoint=((v0+v1+v2)*(1.0f/3.0f)); else SamplePoint=((v0+v1+v2)*(1.0f/3.0f));
@ -703,7 +720,7 @@ static int SingleFaceSubdivisionOld(int sampleNum, const CoordType & v0, const C
CoordType SamplePoint; CoordType SamplePoint;
if(randSample) if(randSample)
{ {
CoordType rb=RandomBaricentric(); CoordType rb=RandomBarycentric();
SamplePoint=v0*rb[0]+v1*rb[1]+v2*rb[2]; SamplePoint=v0*rb[0]+v1*rb[1]+v2*rb[2];
} }
else SamplePoint=((v0+v1+v2)*(1.0f/3.0f)); else SamplePoint=((v0+v1+v2)*(1.0f/3.0f));
@ -819,7 +836,7 @@ static int SingleFaceSimilarDual(FacePointer fp, VertexSampler &ps, int n_sample
CoordType V2((i+0)*segmentLen,(j+1)*segmentLen, 1.0 - ((i+0)*segmentLen+(j+1)*segmentLen) ) ; CoordType V2((i+0)*segmentLen,(j+1)*segmentLen, 1.0 - ((i+0)*segmentLen+(j+1)*segmentLen) ) ;
n_samples++; n_samples++;
if(randomFlag) { if(randomFlag) {
CoordType rb=RandomBaricentric(); CoordType rb=RandomBarycentric();
ps.AddFace(*fp, V0*rb[0]+V1*rb[1]+V2*rb[2]); ps.AddFace(*fp, V0*rb[0]+V1*rb[1]+V2*rb[2]);
} else ps.AddFace(*fp,(V0+V1+V2)/3.0); } else ps.AddFace(*fp,(V0+V1+V2)/3.0);
@ -828,7 +845,7 @@ static int SingleFaceSimilarDual(FacePointer fp, VertexSampler &ps, int n_sample
CoordType V3((i+1)*segmentLen,(j+1)*segmentLen, 1.0 - ((i+1)*segmentLen+(j+1)*segmentLen) ) ; CoordType V3((i+1)*segmentLen,(j+1)*segmentLen, 1.0 - ((i+1)*segmentLen+(j+1)*segmentLen) ) ;
n_samples++; n_samples++;
if(randomFlag) { if(randomFlag) {
CoordType rb=RandomBaricentric(); CoordType rb=RandomBarycentric();
ps.AddFace(*fp, V3*rb[0]+V1*rb[1]+V2*rb[2]); ps.AddFace(*fp, V3*rb[0]+V1*rb[1]+V2*rb[2]);
} else ps.AddFace(*fp,(V3+V1+V2)/3.0); } else ps.AddFace(*fp,(V3+V1+V2)/3.0);
} }