mirror of
https://github.com/lucaspalomodevelop/meshlab.git
synced 2026-03-17 01:54:42 +00:00
hausdorff filter returns values as map of <string, qvariant>
This commit is contained in:
parent
633b5fe5b9
commit
0176d52f89
@ -698,10 +698,16 @@ void FilterDocSampling::initParameterList(const QAction *action, MeshDocument &
|
||||
}
|
||||
}
|
||||
|
||||
bool FilterDocSampling::applyFilter(const QAction *action, MeshDocument &md, std::map<std::string, QVariant>&, unsigned int& /*postConditionMask*/, const RichParameterList & par, vcg::CallBackPos *cb)
|
||||
{
|
||||
switch(ID(action))
|
||||
bool FilterDocSampling::applyFilter(
|
||||
const QAction *action,
|
||||
MeshDocument &md, std::map<std::string,
|
||||
QVariant>& outputValues,
|
||||
unsigned int& /*postConditionMask*/,
|
||||
const RichParameterList & par,
|
||||
vcg::CallBackPos *cb)
|
||||
{
|
||||
switch(ID(action))
|
||||
{
|
||||
case FP_ELEMENT_SUBSAMPLING :
|
||||
{
|
||||
MeshModel *curMM = md.mm();
|
||||
@ -715,22 +721,22 @@ switch(ID(action))
|
||||
errorMessage = "Mesh Element Sampling: cannot sample on faces/edges, mesh has no faces";
|
||||
return false; // can't continue, mesh can't be processed
|
||||
}
|
||||
|
||||
|
||||
MeshModel *mm= md.addNewMesh("", "Element samples", true); // The new mesh is the current one
|
||||
mm->updateDataMask(curMM);
|
||||
|
||||
|
||||
BaseSampler mps(&(mm->cm));
|
||||
|
||||
|
||||
switch(par.getEnum("Sampling"))
|
||||
{
|
||||
case 0 : tri::SurfaceSampling<CMeshO,BaseSampler>::VertexUniform(curMM->cm,mps,par.getInt("SampleNum")); break;
|
||||
case 1 : tri::SurfaceSampling<CMeshO,BaseSampler>::EdgeUniform(curMM->cm,mps,par.getInt("SampleNum"),true); break;
|
||||
case 2 : tri::SurfaceSampling<CMeshO,BaseSampler>::AllFace(curMM->cm,mps); break;
|
||||
case 0 : tri::SurfaceSampling<CMeshO,BaseSampler>::VertexUniform(curMM->cm,mps,par.getInt("SampleNum")); break;
|
||||
case 1 : tri::SurfaceSampling<CMeshO,BaseSampler>::EdgeUniform(curMM->cm,mps,par.getInt("SampleNum"),true); break;
|
||||
case 2 : tri::SurfaceSampling<CMeshO,BaseSampler>::AllFace(curMM->cm,mps); break;
|
||||
}
|
||||
vcg::tri::UpdateBounding<CMeshO>::Box(mm->cm);
|
||||
log("Mesh Element Sampling created a new mesh of %i points",mm->cm.vn);
|
||||
} break;
|
||||
|
||||
|
||||
case FP_TEXEL_SAMPLING :
|
||||
{
|
||||
MeshModel *curMM= md.mm();
|
||||
@ -739,13 +745,13 @@ switch(ID(action))
|
||||
errorMessage = "Texel Sampling requires a mesh with Per Wedge UV parametrization";
|
||||
return false; // can't continue, mesh can't be processed
|
||||
}
|
||||
|
||||
|
||||
MeshModel *mm= md.addNewMesh("", "Texel samples", true); // The new mesh is the current one
|
||||
bool RecoverColor = par.getBool("RecoverColor");
|
||||
BaseSampler mps(&(mm->cm));
|
||||
mps.texSamplingWidth=par.getInt("TextureW");
|
||||
mps.texSamplingHeight=par.getInt("TextureH");
|
||||
|
||||
|
||||
if(RecoverColor && curMM->cm.textures.size()>0)
|
||||
{
|
||||
mps.tex= new QImage(curMM->cm.textures[0].c_str());
|
||||
@ -759,7 +765,7 @@ switch(ID(action))
|
||||
mm->updateDataMask(MeshModel::MM_VERTNORMAL | MeshModel::MM_VERTCOLOR);
|
||||
log("Texel Sampling created a new mesh of %i points", mm->cm.vn);
|
||||
} break;
|
||||
|
||||
|
||||
case FP_MONTECARLO_SAMPLING :
|
||||
{
|
||||
MeshModel *curMM = md.mm();
|
||||
@ -778,13 +784,13 @@ switch(ID(action))
|
||||
errorMessage = "Cannot do weighted samplimg, layer has no Vertex Quality value";
|
||||
return false; // can't continue, mesh can't be processed
|
||||
}
|
||||
|
||||
|
||||
MeshModel *mm= md.addNewMesh("","Montecarlo Samples", true); // The new mesh is the current one
|
||||
mm->updateDataMask(curMM);
|
||||
BaseSampler mps(&(mm->cm));
|
||||
|
||||
mps.perFaceNormal = par.getBool("PerFaceNormal");
|
||||
|
||||
|
||||
mps.perFaceNormal = par.getBool("PerFaceNormal");
|
||||
|
||||
if(par.getBool("EdgeSampling"))
|
||||
{
|
||||
tri::SurfaceSampling<CMeshO,BaseSampler>::EdgeMontecarlo(curMM->cm,mps,par.getInt("SampleNum"),false);
|
||||
@ -798,11 +804,11 @@ switch(ID(action))
|
||||
else
|
||||
tri::SurfaceSampling<CMeshO,BaseSampler>::MontecarloPoisson(curMM->cm,mps,par.getInt("SampleNum"));
|
||||
}
|
||||
|
||||
|
||||
vcg::tri::UpdateBounding<CMeshO>::Box(mm->cm);
|
||||
log("Sampling created a new mesh of %i points", mm->cm.vn);
|
||||
} break;
|
||||
|
||||
|
||||
case FP_STRATIFIED_SAMPLING :
|
||||
{
|
||||
MeshModel *curMM = md.mm();
|
||||
@ -816,44 +822,44 @@ switch(ID(action))
|
||||
errorMessage = "Number of Samples is 0, cannot do anything";
|
||||
return false; // can't continue, mesh can't be processed
|
||||
}
|
||||
|
||||
|
||||
MeshModel *mm= md.addNewMesh("","Subdiv Samples", true); // The new mesh is the current one
|
||||
mm->updateDataMask(curMM);
|
||||
int samplingMethod = par.getEnum("Sampling");
|
||||
BaseSampler mps(&(mm->cm));
|
||||
switch(samplingMethod)
|
||||
{
|
||||
case 0:
|
||||
tri::SurfaceSampling<CMeshO,BaseSampler>::FaceSimilar(curMM->cm,mps,par.getInt("SampleNum"), false ,par.getBool("Random"));
|
||||
log("Similar Sampling created a new mesh of %i points", mm->cm.vn);
|
||||
break;
|
||||
case 1:
|
||||
tri::SurfaceSampling<CMeshO,BaseSampler>::FaceSimilar(curMM->cm,mps,par.getInt("SampleNum"), true ,par.getBool("Random"));
|
||||
log("Dual Similar Sampling created a new mesh of %i points", mm->cm.vn);
|
||||
break;
|
||||
case 2:
|
||||
tri::SurfaceSampling<CMeshO,BaseSampler>::FaceSubdivision(curMM->cm,mps,par.getInt("SampleNum"), par.getBool("Random"));
|
||||
log("Subdivision Sampling created a new mesh of %i points", mm->cm.vn);
|
||||
break;
|
||||
case 3:
|
||||
tri::SurfaceSampling<CMeshO,BaseSampler>::EdgeUniform(curMM->cm,mps,par.getInt("SampleNum"), true);
|
||||
log("Edge Sampling created a new mesh of %i points", mm->cm.vn);
|
||||
break;
|
||||
case 4:
|
||||
tri::SurfaceSampling<CMeshO,BaseSampler>::EdgeUniform(curMM->cm,mps,par.getInt("SampleNum"), false);
|
||||
log("Non Faux Edge Sampling created a new mesh of %i points", mm->cm.vn);
|
||||
break;
|
||||
case 0:
|
||||
tri::SurfaceSampling<CMeshO,BaseSampler>::FaceSimilar(curMM->cm,mps,par.getInt("SampleNum"), false ,par.getBool("Random"));
|
||||
log("Similar Sampling created a new mesh of %i points", mm->cm.vn);
|
||||
break;
|
||||
case 1:
|
||||
tri::SurfaceSampling<CMeshO,BaseSampler>::FaceSimilar(curMM->cm,mps,par.getInt("SampleNum"), true ,par.getBool("Random"));
|
||||
log("Dual Similar Sampling created a new mesh of %i points", mm->cm.vn);
|
||||
break;
|
||||
case 2:
|
||||
tri::SurfaceSampling<CMeshO,BaseSampler>::FaceSubdivision(curMM->cm,mps,par.getInt("SampleNum"), par.getBool("Random"));
|
||||
log("Subdivision Sampling created a new mesh of %i points", mm->cm.vn);
|
||||
break;
|
||||
case 3:
|
||||
tri::SurfaceSampling<CMeshO,BaseSampler>::EdgeUniform(curMM->cm,mps,par.getInt("SampleNum"), true);
|
||||
log("Edge Sampling created a new mesh of %i points", mm->cm.vn);
|
||||
break;
|
||||
case 4:
|
||||
tri::SurfaceSampling<CMeshO,BaseSampler>::EdgeUniform(curMM->cm,mps,par.getInt("SampleNum"), false);
|
||||
log("Non Faux Edge Sampling created a new mesh of %i points", mm->cm.vn);
|
||||
break;
|
||||
}
|
||||
vcg::tri::UpdateBounding<CMeshO>::Box(mm->cm);
|
||||
} break;
|
||||
|
||||
|
||||
case FP_CLUSTERED_SAMPLING :
|
||||
{
|
||||
MeshModel *curMM= md.mm();
|
||||
int samplingMethod = par.getEnum("Sampling");
|
||||
float threshold = par.getAbsPerc("Threshold");
|
||||
bool selected = par.getBool("Selected");
|
||||
|
||||
|
||||
if (selected && curMM->cm.svn == 0 && curMM->cm.sfn == 0) // if no selection at all, fail
|
||||
{
|
||||
log("Clustered Sampling: Cannot apply only on selection: there is no selection");
|
||||
@ -866,48 +872,48 @@ switch(ID(action))
|
||||
tri::UpdateSelection<CMeshO>::VertexFromFaceStrict(curMM->cm);
|
||||
}
|
||||
log("Using only %i selected vertices", curMM->cm.svn);
|
||||
|
||||
|
||||
MeshModel *mm= md.addNewMesh("", "Cluster samples", true); // The new mesh is the current one
|
||||
|
||||
switch(samplingMethod)
|
||||
{
|
||||
case 0 :
|
||||
{
|
||||
tri::Clustering<CMeshO, vcg::tri::AverageColorCell<CMeshO> > ClusteringGrid;
|
||||
ClusteringGrid.Init(curMM->cm.bbox,100000,threshold);
|
||||
ClusteringGrid.AddPointSet(curMM->cm,selected);
|
||||
ClusteringGrid.ExtractPointSet(mm->cm);
|
||||
ClusteringGrid.SelectPointSet(curMM->cm);
|
||||
tri::UpdateSelection<CMeshO>::FaceFromVertexLoose(curMM->cm);
|
||||
log("Similar Sampling created a new mesh of %i points", mm->cm.vn);
|
||||
} break;
|
||||
|
||||
case 1 :
|
||||
{
|
||||
vcg::tri::Clustering<CMeshO, vcg::tri::NearestToCenter<CMeshO> > ClusteringGrid;
|
||||
ClusteringGrid.Init(curMM->cm.bbox,100000,threshold);
|
||||
ClusteringGrid.AddPointSet(curMM->cm,selected);
|
||||
ClusteringGrid.SelectPointSet(curMM->cm);
|
||||
tri::UpdateSelection<CMeshO>::FaceFromVertexLoose(curMM->cm);
|
||||
ClusteringGrid.ExtractPointSet(mm->cm);
|
||||
log("Similar Sampling created a new mesh of %i points", mm->cm.vn);
|
||||
} break;
|
||||
|
||||
switch(samplingMethod)
|
||||
{
|
||||
case 0 :
|
||||
{
|
||||
tri::Clustering<CMeshO, vcg::tri::AverageColorCell<CMeshO> > ClusteringGrid;
|
||||
ClusteringGrid.Init(curMM->cm.bbox,100000,threshold);
|
||||
ClusteringGrid.AddPointSet(curMM->cm,selected);
|
||||
ClusteringGrid.ExtractPointSet(mm->cm);
|
||||
ClusteringGrid.SelectPointSet(curMM->cm);
|
||||
tri::UpdateSelection<CMeshO>::FaceFromVertexLoose(curMM->cm);
|
||||
log("Similar Sampling created a new mesh of %i points", mm->cm.vn);
|
||||
} break;
|
||||
|
||||
case 1 :
|
||||
{
|
||||
vcg::tri::Clustering<CMeshO, vcg::tri::NearestToCenter<CMeshO> > ClusteringGrid;
|
||||
ClusteringGrid.Init(curMM->cm.bbox,100000,threshold);
|
||||
ClusteringGrid.AddPointSet(curMM->cm,selected);
|
||||
ClusteringGrid.SelectPointSet(curMM->cm);
|
||||
tri::UpdateSelection<CMeshO>::FaceFromVertexLoose(curMM->cm);
|
||||
ClusteringGrid.ExtractPointSet(mm->cm);
|
||||
log("Similar Sampling created a new mesh of %i points", mm->cm.vn);
|
||||
} break;
|
||||
}
|
||||
vcg::tri::UpdateBounding<CMeshO>::Box(mm->cm);
|
||||
} break;
|
||||
|
||||
|
||||
case FP_POINTCLOUD_SIMPLIFICATION :
|
||||
{
|
||||
MeshModel *curMM= md.mm();
|
||||
CMeshO::ScalarType radius = par.getAbsPerc("Radius");
|
||||
int sampleNum = par.getInt("SampleNum");
|
||||
|
||||
|
||||
if ((radius == 0.0) && (sampleNum == 0)){
|
||||
log("Point Cloud Simplification: Number of Samples AND Radius are both 0, cannot do anything");
|
||||
errorMessage = "Number of Samples AND Radius are both 0, cannot do anything";
|
||||
return false; // can't continue, mesh can't be processed
|
||||
}
|
||||
|
||||
|
||||
MeshModel *mm= md.addNewMesh("", "Simplified cloud", true); // The new mesh is the current one
|
||||
mm->updateDataMask(curMM);
|
||||
BaseSampler mps(&(mm->cm));
|
||||
@ -917,16 +923,16 @@ switch(ID(action))
|
||||
radius = tri::SurfaceSampling<CMeshO,BaseSampler>::ComputePoissonDiskRadius(curMM->cm,sampleNum);
|
||||
else
|
||||
sampleNum = tri::SurfaceSampling<CMeshO,BaseSampler>::ComputePoissonSampleNum(curMM->cm,radius);
|
||||
|
||||
|
||||
if(par.getBool("ExactNumFlag") && radius==0)
|
||||
tri::SurfaceSampling<CMeshO,BaseSampler>::PoissonDiskPruningByNumber(mps, curMM->cm, sampleNum, radius,pp,0.005);
|
||||
else
|
||||
tri::SurfaceSampling<CMeshO,BaseSampler>::PoissonDiskPruning(mps, curMM->cm, radius,pp);
|
||||
|
||||
|
||||
log("Point Cloud Simplification created a new mesh of %i points", mm->cm.vn);
|
||||
UpdateBounding<CMeshO>::Box(mm->cm);
|
||||
} break;
|
||||
|
||||
|
||||
case FP_POISSONDISK_SAMPLING :
|
||||
{
|
||||
MeshModel *curMM= md.mm();
|
||||
@ -935,18 +941,18 @@ switch(ID(action))
|
||||
tri::SurfaceSampling<CMeshO, BaseSampler>::PoissonDiskParam pp;
|
||||
pp.radiusVariance = par.getFloat("RadiusVariance");
|
||||
bool subsampleFlag = par.getBool("Subsample");
|
||||
|
||||
|
||||
if ((radius == 0.0) && (sampleNum == 0)){
|
||||
log("Poisson disk Sampling: Number of Samples AND Radius are both 0, cannot do anything");
|
||||
errorMessage = "Number of Samples AND Radius are both 0, cannot do anything";
|
||||
return false; // can't continue, mesh can't be processed
|
||||
}
|
||||
|
||||
|
||||
if (radius == 0)
|
||||
radius = tri::SurfaceSampling<CMeshO, BaseSampler>::ComputePoissonDiskRadius(curMM->cm, sampleNum);
|
||||
else
|
||||
sampleNum = tri::SurfaceSampling<CMeshO, BaseSampler>::ComputePoissonSampleNum(curMM->cm, radius);
|
||||
|
||||
|
||||
if (pp.radiusVariance != 1.0)
|
||||
{
|
||||
if (!curMM->hasDataMask(MeshModel::MM_VERTQUALITY)) {
|
||||
@ -957,22 +963,22 @@ switch(ID(action))
|
||||
pp.adaptiveRadiusFlag = true;
|
||||
log("Variable Density variance is %f, radius can vary from %f to %f", pp.radiusVariance, radius / pp.radiusVariance, radius*pp.radiusVariance);
|
||||
}
|
||||
|
||||
|
||||
if (curMM->cm.fn == 0 && subsampleFlag == false)
|
||||
{
|
||||
log("Poisson disk Sampling: Current mesh has no triangles. We cannot create a montecarlo sampling of the surface. Please select the Subsample flag");
|
||||
errorMessage = "Current mesh has no triangles. We cannot create a montecarlo sampling of the surface.<br> Please select the Subsample flag";
|
||||
return false; // cannot continue
|
||||
}
|
||||
|
||||
|
||||
MeshModel *mm= md.addNewMesh("","Poisson-disk Samples", true); // The new mesh is the current one
|
||||
mm->updateDataMask(curMM);
|
||||
|
||||
|
||||
log("Computing %i Poisson Samples for an expected radius of %f",sampleNum,radius);
|
||||
|
||||
|
||||
// first of all generate montecarlo samples for fast lookup
|
||||
CMeshO *presampledMesh=0;
|
||||
|
||||
|
||||
CMeshO MontecarloMesh; // this mesh is used only if we need real poisson sampling (and therefore we need to choose points different from the starting mesh vertices)
|
||||
if(subsampleFlag)
|
||||
presampledMesh = &(curMM->cm);
|
||||
@ -986,7 +992,7 @@ switch(ID(action))
|
||||
}
|
||||
else
|
||||
presampledMesh=&MontecarloMesh;
|
||||
|
||||
|
||||
QElapsedTimer tt;tt.start();
|
||||
BaseSampler sampler(presampledMesh);
|
||||
sampler.qualitySampling=true;
|
||||
@ -997,7 +1003,7 @@ switch(ID(action))
|
||||
presampledMesh->bbox = curMM->cm.bbox; // we want the same bounding box
|
||||
log("Generated %i Montecarlo Samples (%i msec)",presampledMesh->vn,tt.elapsed());
|
||||
}
|
||||
|
||||
|
||||
BaseSampler mps(&(mm->cm));
|
||||
if(par.getBool("RefineFlag"))
|
||||
{
|
||||
@ -1011,14 +1017,14 @@ switch(ID(action))
|
||||
tri::SurfaceSampling<CMeshO,BaseSampler>::PoissonDiskPruningByNumber(mps, *presampledMesh, sampleNum, radius,pp,0.005);
|
||||
else
|
||||
tri::SurfaceSampling<CMeshO,BaseSampler>::PoissonDiskPruning(mps, *presampledMesh, radius,pp);
|
||||
|
||||
|
||||
//tri::SurfaceSampling<CMeshO,BaseSampler>::PoissonDisk(curMM->cm, mps, *presampledMesh, radius,pp);
|
||||
vcg::tri::UpdateBounding<CMeshO>::Box(mm->cm);
|
||||
Point3i &g=pp.pds.gridSize;
|
||||
log("Grid size was %i %i %i (%i allocated on %i)",g[0],g[1],g[2], pp.pds.gridCellNum, g[0]*g[1]*g[2]);
|
||||
log("Poisson Disk Sampling created a new mesh of %i points", mm->cm.vn);
|
||||
} break;
|
||||
|
||||
|
||||
case FP_HAUSDORFF_DISTANCE :
|
||||
{
|
||||
MeshModel* mm0 = par.getMesh("SampledMesh"); // surface where we choose the random samples
|
||||
@ -1029,13 +1035,13 @@ switch(ID(action))
|
||||
bool sampleFauxEdge=par.getBool("SampleFauxEdge");
|
||||
bool sampleFace=par.getBool("SampleFace");
|
||||
float distUpperBound = par.getAbsPerc("MaxDist");
|
||||
|
||||
|
||||
if (mm0 == mm1){
|
||||
log("Hausdorff Distance: cannot compute, it is the same mesh");
|
||||
errorMessage = "Cannot compute, it is the same mesh";
|
||||
return false; // can't continue, mesh can't be processed
|
||||
}
|
||||
|
||||
|
||||
if(sampleEdge && mm0->cm.fn==0) {
|
||||
log("Disabled edge sampling. Meaningless when sampling point clouds");
|
||||
sampleEdge=false;
|
||||
@ -1044,86 +1050,94 @@ switch(ID(action))
|
||||
log("Disabled face sampling. Meaningless when sampling point clouds");
|
||||
sampleFace=false;
|
||||
}
|
||||
|
||||
|
||||
// the meshes have to be transformed
|
||||
if (mm0->cm.Tr != Matrix44m::Identity())
|
||||
tri::UpdatePosition<CMeshO>::Matrix(mm0->cm, mm0->cm.Tr, true);
|
||||
if (mm1->cm.Tr != Matrix44m::Identity())
|
||||
tri::UpdatePosition<CMeshO>::Matrix(mm1->cm, mm1->cm.Tr, true);
|
||||
|
||||
|
||||
mm0->updateDataMask(MeshModel::MM_VERTQUALITY);
|
||||
mm1->updateDataMask(MeshModel::MM_VERTQUALITY);
|
||||
mm1->updateDataMask(MeshModel::MM_FACEMARK);
|
||||
tri::UpdateNormal<CMeshO>::PerFaceNormalized(mm1->cm);
|
||||
|
||||
|
||||
MeshModel *samplePtMesh =0;
|
||||
MeshModel *closestPtMesh =0;
|
||||
HausdorffSampler<CMeshO> hs(&(mm1->cm));
|
||||
if(saveSampleFlag)
|
||||
{
|
||||
closestPtMesh=md.addNewMesh("","Hausdorff Closest Points", false); // the new mesh is NOT the current one (byproduct of measurement)
|
||||
closestPtMesh->updateDataMask(MeshModel::MM_VERTCOLOR | MeshModel::MM_VERTQUALITY);
|
||||
samplePtMesh = md.addNewMesh("", "Hausdorff Sample Point", false); // the new mesh is NOT the current one (byproduct of measurement)
|
||||
samplePtMesh->updateDataMask(MeshModel::MM_VERTCOLOR | MeshModel::MM_VERTQUALITY);
|
||||
hs.init(&(samplePtMesh->cm),&(closestPtMesh->cm));
|
||||
closestPtMesh=md.addNewMesh("","Hausdorff Closest Points", false); // the new mesh is NOT the current one (byproduct of measurement)
|
||||
closestPtMesh->updateDataMask(MeshModel::MM_VERTCOLOR | MeshModel::MM_VERTQUALITY);
|
||||
samplePtMesh = md.addNewMesh("", "Hausdorff Sample Point", false); // the new mesh is NOT the current one (byproduct of measurement)
|
||||
samplePtMesh->updateDataMask(MeshModel::MM_VERTCOLOR | MeshModel::MM_VERTQUALITY);
|
||||
hs.init(&(samplePtMesh->cm),&(closestPtMesh->cm));
|
||||
}
|
||||
|
||||
|
||||
hs.dist_upper_bound = distUpperBound;
|
||||
|
||||
|
||||
qDebug("Sampled mesh has %7i vert %7i face",mm0->cm.vn,mm0->cm.fn);
|
||||
qDebug("Searched mesh has %7i vert %7i face",mm1->cm.vn,mm1->cm.fn);
|
||||
qDebug("Max sampling distance %f on a bbox diag of %f",distUpperBound,mm1->cm.bbox.Diag());
|
||||
|
||||
|
||||
if(sampleVert)
|
||||
tri::SurfaceSampling<CMeshO,HausdorffSampler<CMeshO> >::VertexUniform(mm0->cm,hs,par.getInt("SampleNum"));
|
||||
tri::SurfaceSampling<CMeshO,HausdorffSampler<CMeshO> >::VertexUniform(mm0->cm,hs,par.getInt("SampleNum"));
|
||||
if(sampleEdge)
|
||||
tri::SurfaceSampling<CMeshO,HausdorffSampler<CMeshO> >::EdgeUniform(mm0->cm,hs,par.getInt("SampleNum"),sampleFauxEdge);
|
||||
tri::SurfaceSampling<CMeshO,HausdorffSampler<CMeshO> >::EdgeUniform(mm0->cm,hs,par.getInt("SampleNum"),sampleFauxEdge);
|
||||
if(sampleFace)
|
||||
tri::SurfaceSampling<CMeshO,HausdorffSampler<CMeshO> >::Montecarlo(mm0->cm,hs,par.getInt("SampleNum"));
|
||||
|
||||
tri::SurfaceSampling<CMeshO,HausdorffSampler<CMeshO> >::Montecarlo(mm0->cm,hs,par.getInt("SampleNum"));
|
||||
|
||||
// the meshes have to return to their original position
|
||||
if (mm0->cm.Tr != Matrix44m::Identity())
|
||||
tri::UpdatePosition<CMeshO>::Matrix(mm0->cm, Inverse(mm0->cm.Tr), true);
|
||||
if (mm1->cm.Tr != Matrix44m::Identity())
|
||||
tri::UpdatePosition<CMeshO>::Matrix(mm1->cm, Inverse(mm1->cm.Tr), true);
|
||||
|
||||
|
||||
log("Hausdorff Distance computed");
|
||||
log(" Sampled %i pts (rng: 0) on %s searched closest on %s",hs.n_total_samples,qUtf8Printable(mm0->label()),qUtf8Printable(mm1->label()));
|
||||
log(" min : %f max %f mean : %f RMS : %f",hs.getMinDist(),hs.getMaxDist(),hs.getMeanDist(),hs.getRMSDist());
|
||||
float d = mm0->cm.bbox.Diag();
|
||||
log("Values w.r.t. BBox Diag (%f)",d);
|
||||
log(" min : %f max %f mean : %f RMS : %f\n",hs.getMinDist()/d,hs.getMaxDist()/d,hs.getMeanDist()/d,hs.getRMSDist()/d);
|
||||
|
||||
|
||||
|
||||
outputValues.clear();
|
||||
outputValues["n_samples"] = QVariant(hs.n_total_samples);
|
||||
outputValues["min"] = QVariant(hs.getMinDist());
|
||||
outputValues["max"] = QVariant(hs.getMaxDist());
|
||||
outputValues["mean"] = QVariant(hs.getMeanDist());
|
||||
outputValues["RMS"] = QVariant(hs.getRMSDist());
|
||||
outputValues["diag_mesh_0"] = QVariant(d);
|
||||
outputValues["diag_mesh_1"] = QVariant(mm1->cm.bbox.Diag());
|
||||
|
||||
if(saveSampleFlag)
|
||||
{
|
||||
tri::UpdateBounding<CMeshO>::Box(samplePtMesh->cm);
|
||||
tri::UpdateBounding<CMeshO>::Box(closestPtMesh->cm);
|
||||
|
||||
tri::UpdateColor<CMeshO>::PerVertexQualityRamp(samplePtMesh->cm);
|
||||
tri::UpdateColor<CMeshO>::PerVertexQualityRamp(closestPtMesh->cm);
|
||||
tri::UpdateBounding<CMeshO>::Box(samplePtMesh->cm);
|
||||
tri::UpdateBounding<CMeshO>::Box(closestPtMesh->cm);
|
||||
|
||||
tri::UpdateColor<CMeshO>::PerVertexQualityRamp(samplePtMesh->cm);
|
||||
tri::UpdateColor<CMeshO>::PerVertexQualityRamp(closestPtMesh->cm);
|
||||
}
|
||||
} break;
|
||||
|
||||
|
||||
case FP_DISTANCE_REFERENCE:
|
||||
{
|
||||
MeshModel* mm0 = par.getMesh("MeasureMesh"); // this mesh gets measured.
|
||||
MeshModel* mm1 = par.getMesh("RefMesh"); // this is the reference mesh
|
||||
bool useSigned = par.getBool("SignedDist");
|
||||
float maxDistABS = par.getAbsPerc("MaxDist");
|
||||
|
||||
|
||||
if (mm0 == mm1){
|
||||
log("Distance from Reference: cannot compute, it is the same mesh");
|
||||
errorMessage = "Cannot compute, it is the same mesh";
|
||||
return false; // can't continue, mesh can't be processed
|
||||
}
|
||||
|
||||
|
||||
// the meshes have to return to their original position
|
||||
if (mm0->cm.Tr != Matrix44m::Identity())
|
||||
tri::UpdatePosition<CMeshO>::Matrix(mm0->cm, mm0->cm.Tr, true);
|
||||
if (mm1->cm.Tr != Matrix44m::Identity())
|
||||
tri::UpdatePosition<CMeshO>::Matrix(mm1->cm, mm1->cm.Tr, true);
|
||||
|
||||
|
||||
// add quality to vertex of measured mesh
|
||||
mm0->updateDataMask(MeshModel::MM_VERTQUALITY);
|
||||
// if reference has faces, recompute and normalize normals
|
||||
@ -1132,24 +1146,24 @@ switch(ID(action))
|
||||
tri::UpdateNormal<CMeshO>::PerFaceNormalized(mm1->cm);
|
||||
tri::UpdateNormal<CMeshO>::PerVertexNormalized(mm1->cm);
|
||||
}
|
||||
mm1->updateDataMask(MeshModel::MM_FACEMARK);
|
||||
|
||||
mm1->updateDataMask(MeshModel::MM_FACEMARK);
|
||||
|
||||
SimpleDistanceSampler ds(&(mm1->cm), useSigned, maxDistABS);
|
||||
|
||||
|
||||
tri::SurfaceSampling<CMeshO, SimpleDistanceSampler>::AllVertex(mm0->cm, ds);
|
||||
|
||||
|
||||
// the meshes have to return to their original position
|
||||
if (mm0->cm.Tr != Matrix44m::Identity())
|
||||
tri::UpdatePosition<CMeshO>::Matrix(mm0->cm, Inverse(mm0->cm.Tr), true);
|
||||
if (mm1->cm.Tr != Matrix44m::Identity())
|
||||
tri::UpdatePosition<CMeshO>::Matrix(mm1->cm, Inverse(mm1->cm.Tr), true);
|
||||
|
||||
|
||||
log("Distance from Reference Mesh computed");
|
||||
log(" Sampled %i vertices on %s searched closest on %s", mm0->cm.vn, qUtf8Printable(mm0->label()), qUtf8Printable(mm1->label()));
|
||||
log(" min : %f max %f mean : %f RMS : %f", ds.getMaxDist(), ds.getMaxDist(), ds.getMeanDist(), ds.getRMSDist());
|
||||
|
||||
|
||||
} break;
|
||||
|
||||
|
||||
case FP_VERTEX_RESAMPLING :
|
||||
{
|
||||
MeshModel* srcMesh = par.getMesh("SourceMesh"); // mesh whose attribute are read
|
||||
@ -1162,7 +1176,7 @@ switch(ID(action))
|
||||
bool qualityT = par.getBool("QualityTransfer");
|
||||
bool selectionT = par.getBool("SelectionTransfer");
|
||||
bool distquality = par.getBool("QualityDistance");
|
||||
|
||||
|
||||
if (srcMesh == trgMesh){
|
||||
log("Vertex Attribute Transfer: cannot compute, it is the same mesh");
|
||||
errorMessage = "Cannot compute, it is the same mesh";
|
||||
@ -1174,7 +1188,7 @@ switch(ID(action))
|
||||
errorMessage = QString("You have to choose at least one attribute to be sampled");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (onlySelected && trgMesh->cm.svn == 0 && trgMesh->cm.sfn == 0) // if no selection at all, fail
|
||||
{
|
||||
log("Vertex Attribute Transfer: Cannot apply only on selection: there is no selection");
|
||||
@ -1186,19 +1200,19 @@ switch(ID(action))
|
||||
tri::UpdateSelection<CMeshO>::VertexClear(trgMesh->cm);
|
||||
tri::UpdateSelection<CMeshO>::VertexFromFaceLoose(trgMesh->cm);
|
||||
}
|
||||
|
||||
|
||||
// the meshes have to be transformed
|
||||
if (srcMesh->cm.Tr != Matrix44m::Identity())
|
||||
tri::UpdatePosition<CMeshO>::Matrix(srcMesh->cm, srcMesh->cm.Tr, true);
|
||||
if (trgMesh->cm.Tr != Matrix44m::Identity())
|
||||
tri::UpdatePosition<CMeshO>::Matrix(trgMesh->cm, trgMesh->cm.Tr, true);
|
||||
|
||||
|
||||
srcMesh->updateDataMask(MeshModel::MM_FACEMARK);
|
||||
tri::UpdateNormal<CMeshO>::PerFaceNormalized(srcMesh->cm);
|
||||
|
||||
|
||||
LocalRedetailSampler rs;
|
||||
rs.init(&(srcMesh->cm),cb,trgMesh->cm.vn);
|
||||
|
||||
|
||||
rs.dist_upper_bound = upperbound;
|
||||
rs.colorFlag = colorT;
|
||||
rs.coordFlag = geomT;
|
||||
@ -1206,25 +1220,25 @@ switch(ID(action))
|
||||
rs.qualityFlag = qualityT;
|
||||
rs.selectionFlag = selectionT;
|
||||
rs.storeDistanceAsQualityFlag = distquality;
|
||||
|
||||
|
||||
if(rs.colorFlag) trgMesh->updateDataMask(MeshModel::MM_VERTCOLOR);
|
||||
if(rs.qualityFlag) trgMesh->updateDataMask(MeshModel::MM_VERTQUALITY);
|
||||
|
||||
|
||||
qDebug("Source mesh has %7i vert %7i face",srcMesh->cm.vn,srcMesh->cm.fn);
|
||||
qDebug("Target mesh has %7i vert %7i face",trgMesh->cm.vn,trgMesh->cm.fn);
|
||||
|
||||
|
||||
tri::SurfaceSampling<CMeshO, LocalRedetailSampler>::VertexUniform(trgMesh->cm, rs, trgMesh->cm.vn, onlySelected);
|
||||
|
||||
|
||||
if(rs.coordFlag) tri::UpdateNormal<CMeshO>::PerFaceNormalized(trgMesh->cm);
|
||||
|
||||
|
||||
// the meshes have to return to their original position
|
||||
if (srcMesh->cm.Tr != Matrix44m::Identity())
|
||||
tri::UpdatePosition<CMeshO>::Matrix(srcMesh->cm, Inverse(srcMesh->cm.Tr), true);
|
||||
if (trgMesh->cm.Tr != Matrix44m::Identity())
|
||||
tri::UpdatePosition<CMeshO>::Matrix(trgMesh->cm, Inverse(trgMesh->cm.Tr), true);
|
||||
|
||||
|
||||
} break;
|
||||
|
||||
|
||||
case FP_UNIFORM_MESH_RESAMPLING :
|
||||
{
|
||||
if (md.mm()->cm.fn==0) {
|
||||
@ -1232,27 +1246,27 @@ switch(ID(action))
|
||||
errorMessage = "Uniform Mesh Resampling requires a mesh with faces,<br> it does not work on Point Clouds";
|
||||
return false; // can't continue, mesh can't be processed
|
||||
}
|
||||
|
||||
|
||||
CMeshO::ScalarType voxelSize = par.getAbsPerc("CellSize");
|
||||
float offsetThr = par.getAbsPerc("Offset");
|
||||
bool discretizeFlag = par.getBool("discretize");
|
||||
bool multiSampleFlag = par.getBool("multisample");
|
||||
bool absDistFlag = par.getBool("absDist");
|
||||
bool mergeCloseVert = par.getBool("mergeCloseVert");
|
||||
|
||||
|
||||
MeshModel *baseMesh= md.mm();
|
||||
MeshModel *offsetMesh = md.addNewMesh("", "Offset mesh", true); // the new mesh is the current one
|
||||
baseMesh->updateDataMask(MeshModel::MM_FACEMARK);
|
||||
|
||||
|
||||
Point3i volumeDim;
|
||||
Box3m volumeBox = baseMesh->cm.bbox;
|
||||
volumeBox.Offset(volumeBox.Diag()/10.0f+abs(offsetThr));
|
||||
BestDim(volumeBox , voxelSize, volumeDim );
|
||||
|
||||
|
||||
log("Resampling mesh using a volume of %i x %i x %i",volumeDim[0],volumeDim[1],volumeDim[2]);
|
||||
log(" VoxelSize is %f, offset is %f ", voxelSize,offsetThr);
|
||||
log(" Mesh Box is %f %f %f",baseMesh->cm.bbox.DimX(),baseMesh->cm.bbox.DimY(),baseMesh->cm.bbox.DimZ() );
|
||||
|
||||
|
||||
tri::Resampler<CMeshO,CMeshO>::Resample(baseMesh->cm, offsetMesh->cm, volumeBox, volumeDim, voxelSize*3.5, offsetThr,discretizeFlag,multiSampleFlag,absDistFlag, cb);
|
||||
tri::UpdateBounding<CMeshO>::Box(offsetMesh->cm);
|
||||
if(mergeCloseVert)
|
||||
@ -1263,13 +1277,13 @@ switch(ID(action))
|
||||
}
|
||||
tri::UpdateNormal<CMeshO>::PerVertexPerFace(offsetMesh->cm);
|
||||
} break;
|
||||
|
||||
|
||||
case FP_VORONOI_COLORING :
|
||||
{
|
||||
MeshModel* mmM = par.getMesh("ColoredMesh"); // surface where we choose the random samples
|
||||
MeshModel* mmV = par.getMesh("VertexMesh"); // surface that is sought for the closest point to each sample.
|
||||
bool backwardFlag = par.getBool("backward");
|
||||
|
||||
|
||||
tri::Clean<CMeshO>::RemoveUnreferencedVertex(mmM->cm);
|
||||
tri::Allocator<CMeshO>::CompactVertexVector(mmM->cm);
|
||||
tri::Allocator<CMeshO>::CompactFaceVector(mmM->cm);
|
||||
@ -1278,17 +1292,17 @@ switch(ID(action))
|
||||
// Fills the point vector with the position of the Point cloud
|
||||
for(CMeshO::VertexIterator vi= mmV->cm.vert.begin(); vi!= mmV->cm.vert.end(); ++vi) if(!(*vi).IsD())
|
||||
vecP.push_back((*vi).cP());
|
||||
|
||||
|
||||
vector<CMeshO::VertexPointer> vecV; // points to vertices of ColoredMesh;
|
||||
tri::VoronoiProcessing<CMeshO>::SeedToVertexConversion (mmM->cm, vecP, vecV);
|
||||
log("Converted %ui points into %ui vertex ",vecP.size(),vecV.size());
|
||||
tri::EuclideanDistance<CMeshO> edFunc;
|
||||
tri::VoronoiProcessing<CMeshO>::ComputePerVertexSources(mmM->cm,vecV,edFunc);
|
||||
|
||||
|
||||
for(uint i=0;i<vecV.size();++i) vecV[i]->C()=Color4b::Red;
|
||||
tri::VoronoiProcessing<CMeshO>::VoronoiColoring(mmM->cm,backwardFlag);
|
||||
} break;
|
||||
|
||||
|
||||
case FP_DISK_COLORING :
|
||||
{
|
||||
MeshModel* mmM = par.getMesh("ColoredMesh");
|
||||
@ -1304,31 +1318,31 @@ switch(ID(action))
|
||||
sht.Set(mmM->cm.vert.begin(),mmM->cm.vert.end());
|
||||
std::vector<CMeshO::VertexType*> closests;
|
||||
float radius = par.getDynamicFloat("Radius");
|
||||
|
||||
|
||||
for(CMeshO::VertexIterator viv = mmV->cm.vert.begin(); viv!= mmV->cm.vert.end(); ++viv) if(!(*viv).IsD())
|
||||
{
|
||||
Point3m p = viv->cP();
|
||||
if(sampleRadiusFlag) radius = viv->Q();
|
||||
Box3m bb(p-Point3m(radius,radius,radius),p+Point3m(radius,radius,radius));
|
||||
GridGetInBox(sht, markerFunctor, bb, closests);
|
||||
|
||||
for(size_t i=0; i<closests.size(); ++i)
|
||||
{
|
||||
float dist;
|
||||
if(approximateGeodeticFlag)
|
||||
dist = ApproximateGeodesicDistance(viv->cP(),viv->cN(),closests[i]->cP(),closests[i]->cN());
|
||||
else
|
||||
dist = Distance(p,closests[i]->cP());
|
||||
|
||||
if(dist < radius && closests[i]->Q() > dist)
|
||||
Point3m p = viv->cP();
|
||||
if(sampleRadiusFlag) radius = viv->Q();
|
||||
Box3m bb(p-Point3m(radius,radius,radius),p+Point3m(radius,radius,radius));
|
||||
GridGetInBox(sht, markerFunctor, bb, closests);
|
||||
|
||||
for(size_t i=0; i<closests.size(); ++i)
|
||||
{
|
||||
closests[i]->Q() = dist;
|
||||
closests[i]->C().lerp(Color4b::White,Color4b::Red,dist/radius);
|
||||
float dist;
|
||||
if(approximateGeodeticFlag)
|
||||
dist = ApproximateGeodesicDistance(viv->cP(),viv->cN(),closests[i]->cP(),closests[i]->cN());
|
||||
else
|
||||
dist = Distance(p,closests[i]->cP());
|
||||
|
||||
if(dist < radius && closests[i]->Q() > dist)
|
||||
{
|
||||
closests[i]->Q() = dist;
|
||||
closests[i]->C().lerp(Color4b::White,Color4b::Red,dist/radius);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
|
||||
case FP_REGULAR_RECURSIVE_SAMPLING :
|
||||
{
|
||||
if (md.mm()->cm.fn==0) {
|
||||
@ -1338,24 +1352,24 @@ switch(ID(action))
|
||||
}
|
||||
float CellSize = par.getAbsPerc("CellSize");
|
||||
float offset=par.getAbsPerc("Offset");
|
||||
|
||||
|
||||
MeshModel *mmM= md.mm();
|
||||
MeshModel *mm= md.addNewMesh("","Recursive Samples",true); // the new mesh is the current one
|
||||
|
||||
|
||||
tri::Clean<CMeshO>::RemoveUnreferencedVertex(mmM->cm);
|
||||
tri::Allocator<CMeshO>::CompactEveryVector(mmM->cm);
|
||||
|
||||
|
||||
tri::UpdateNormal<CMeshO>::PerFaceNormalized(mmM->cm);
|
||||
std::vector<Point3m> pvec;
|
||||
|
||||
|
||||
tri::SurfaceSampling<CMeshO,LocalRedetailSampler>::RegularRecursiveOffset(mmM->cm,pvec, offset, CellSize);
|
||||
qDebug("Generated %i points",int(pvec.size()));
|
||||
tri::BuildMeshFromCoordVector(mm->cm,pvec);
|
||||
} break;
|
||||
|
||||
|
||||
default : assert(0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
FilterPluginInterface::FilterClass FilterDocSampling::getClass(const QAction *action) const
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user