completed the refactoring of the variable disk sampling

This commit is contained in:
Paolo Cignoni 2009-01-29 00:16:00 +00:00
parent eaa4d2232b
commit 92f9a2026b
1 changed files with 42 additions and 13 deletions

View File

@ -705,12 +705,41 @@ struct PoissonDiskParam
PoissonDiskParam() PoissonDiskParam()
{ {
adaptiveRadiusFlag = false; adaptiveRadiusFlag = false;
radiusVariance =1;
MAXLEVELS = 5; MAXLEVELS = 5;
} }
bool adaptiveRadiusFlag; bool adaptiveRadiusFlag;
float radiusVariance;
int MAXLEVELS; int MAXLEVELS;
}; };
static ScalarType ComputePoissonDiskRadius(MetroMesh &origMesh, int sampleNum)
{
ScalarType meshArea = Stat<MetroMesh>::ComputeMeshArea(origMesh);
ScalarType diskRadius = sqrt(meshArea / (0.7 * M_PI * sampleNum)); // 0.7 is a density factor
return diskRadius;
}
static int ComputePoissonSampleNum(MetroMesh &origMesh, ScalarType diskRadius)
{
ScalarType meshArea = Stat<MetroMesh>::ComputeMeshArea(origMesh);
int sampleNum = meshArea / (diskRadius*diskRadius *M_PI *0.7) ; // 0.7 is a density factor
return sampleNum;
}
static void ComputePoissonSampleRadii(MetroMesh &sampleMesh, ScalarType diskRadius, ScalarType radiusVariance)
{
VertexIterator vi;
std::pair<float,float> minmax = tri::Stat<MetroMesh>::ComputePerVertexQualityMinMax( sampleMesh);
float minRad = diskRadius / radiusVariance;
float maxRad = diskRadius * radiusVariance;
float deltaQ = minmax.second-minmax.first;
float deltaRad = maxRad-minRad;
for (vi = sampleMesh.vert.begin(); vi != sampleMesh.vert.end(); vi++)
{
(*vi).Q() = minRad + deltaRad*((*vi).Q() - minmax.first/deltaQ);
}
}
/** Compute a Poisson-disk sampling of the surface. /** Compute a Poisson-disk sampling of the surface.
* The radius of the disk is computed according to the estimated sampling density. * The radius of the disk is computed according to the estimated sampling density.
@ -722,7 +751,7 @@ struct PoissonDiskParam
* IEEE Symposium on Interactive Ray Tracing, 2007, * IEEE Symposium on Interactive Ray Tracing, 2007,
* 10-12 Sept. 2007, pp. 129-132. * 10-12 Sept. 2007, pp. 129-132.
*/ */
static void Poissondisk(MetroMesh &origMesh, VertexSampler &ps, MetroMesh &montecarloMesh, int sampleNum, const struct PoissonDiskParam pp=PoissonDiskParam()) static void Poissondisk(MetroMesh &origMesh, VertexSampler &ps, MetroMesh &montecarloMesh, ScalarType diskRadius, const struct PoissonDiskParam pp=PoissonDiskParam())
{ {
int cellusedcounter[20]; // cells used for each level int cellusedcounter[20]; // cells used for each level
int cellstosubdividecounter[20]; // cells to subdivide for each level int cellstosubdividecounter[20]; // cells to subdivide for each level
@ -741,7 +770,6 @@ static void Poissondisk(MetroMesh &origMesh, VertexSampler &ps, MetroMesh &monte
MetroMesh supportMesh; MetroMesh supportMesh;
const int MAXLEVELS = 5; // maximum level of subdivision
// 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;
@ -750,9 +778,6 @@ static void Poissondisk(MetroMesh &origMesh, VertexSampler &ps, MetroMesh &monte
SampleSHT checkSHT; SampleSHT checkSHT;
// initialize spatial hash table for searching // initialize spatial hash table for searching
ScalarType meshArea = Stat<MetroMesh>::ComputeMeshArea(origMesh);
ScalarType diskRadius = sqrt(meshArea / (0.7 * 3.1415 * sampleNum)); // 0.7 is a density factor
ScalarType cellsize = diskRadius / sqrt(3.0); ScalarType cellsize = diskRadius / sqrt(3.0);
// inflating // inflating
@ -797,7 +822,11 @@ static void Poissondisk(MetroMesh &origMesh, VertexSampler &ps, MetroMesh &monte
Point3i *currentCell; Point3i *currentCell;
vcg::Box3<ScalarType> currentBox; vcg::Box3<ScalarType> currentBox;
int level = 0; int level = 0;
// if we are doing variable density sampling we have to prepare the random samples quality with the correct expected radii.
if(pp.adaptiveRadiusFlag)
ComputePoissonSampleRadii(montecarloMesh, diskRadius, pp.radiusVariance);
do do
{ {
// extract a cell (C) from the active cell list (with probability proportional to cell's volume) // extract a cell (C) from the active cell list (with probability proportional to cell's volume)
@ -843,7 +872,7 @@ static void Poissondisk(MetroMesh &origMesh, VertexSampler &ps, MetroMesh &monte
// vr spans between 3.0*r and r / 4.0 according to vertex quality // vr spans between 3.0*r and r / 4.0 according to vertex quality
ScalarType sampleRadius = diskRadius; ScalarType sampleRadius = diskRadius;
if(pp.adaptiveRadiusFlag) sampleRadius = diskRadius * sp->Q(); if(pp.adaptiveRadiusFlag) sampleRadius = sp->Q();
if (checkPoissonDisk(*ps.m, checkSHT, sp->cP(), sampleRadius)) if (checkPoissonDisk(*ps.m, checkSHT, sp->cP(), sampleRadius))
{ {
@ -900,7 +929,7 @@ static void Poissondisk(MetroMesh &origMesh, VertexSampler &ps, MetroMesh &monte
qDebug("PDS: Completed Level %i, added %i samples",level,samplesaccepted[level]); qDebug("PDS: Completed Level %i, added %i samples",level,samplesaccepted[level]);
level++; level++;
} while(level < MAXLEVELS); } while(level < pp.MAXLEVELS);
// write some statistics // write some statistics
@ -909,19 +938,19 @@ static void Poissondisk(MetroMesh &origMesh, VertexSampler &ps, MetroMesh &monte
{ {
QTextStream out(&outfile); QTextStream out(&outfile);
for (int k = 0; k < MAXLEVELS; k++) for (int k = 0; k < pp.MAXLEVELS; k++)
out << "Cells used for level " << k << ": " << cellusedcounter[k] << endl; out << "Cells used for level " << k << ": " << cellusedcounter[k] << endl;
for (int k = 0; k < MAXLEVELS; k++) for (int k = 0; k < pp.MAXLEVELS; k++)
out << "Cells to subdivide for level " << k << ": " << cellstosubdividecounter[k] << endl; out << "Cells to subdivide for level " << k << ": " << cellstosubdividecounter[k] << endl;
for (int k = 0; k < MAXLEVELS; k++) for (int k = 0; k < pp.MAXLEVELS; k++)
out << "Vertices counter for level " << k << ": " << verticescounter[k] << endl; out << "Vertices counter for level " << k << ": " << verticescounter[k] << endl;
for (int k = 0; k < MAXLEVELS; k++) for (int k = 0; k < pp.MAXLEVELS; k++)
out << "Samples generated for level " << k << ": " << samplesgenerated[k] << endl; out << "Samples generated for level " << k << ": " << samplesgenerated[k] << endl;
for (int k = 0; k < MAXLEVELS; k++) for (int k = 0; k < pp.MAXLEVELS; k++)
out << "Samples accepted for level " << k << ": " << samplesaccepted[k] << endl; out << "Samples accepted for level " << k << ": " << samplesaccepted[k] << endl;
} }