From f8499de7bb14ed7ac6beba892ae9efac19c4adbb Mon Sep 17 00:00:00 2001 From: Paolo Cignoni cignoni Date: Tue, 17 Jun 2014 15:25:20 +0000 Subject: [PATCH] Filter Change: Create->Random Sphere now is Create->Point on a Sphere It allows the creation of points randomly generated using a Poisson Disk distribution or using the Dave Rusin's disco ball algorithm for the regular placement of points on a sphere. --- .../filter_create/filter_create.cpp | 64 +++++++++++-------- 1 file changed, 38 insertions(+), 26 deletions(-) diff --git a/src/meshlabplugins/filter_create/filter_create.cpp b/src/meshlabplugins/filter_create/filter_create.cpp index 6f721d22e..eec3bf9fe 100644 --- a/src/meshlabplugins/filter_create/filter_create.cpp +++ b/src/meshlabplugins/filter_create/filter_create.cpp @@ -24,6 +24,8 @@ #include #include #include +#include + using namespace vcg; using namespace tri; @@ -48,7 +50,7 @@ QString FilterCreate::filterName(FilterIDType filterId) const case CR_ANNULUS : return QString("Annulus"); case CR_SPHERE: return QString("Sphere"); case CR_SPHERE_CAP: return QString("Sphere Cap"); - case CR_RANDOM_SPHERE: return QString("Random Sphere"); + case CR_RANDOM_SPHERE: return QString("Points on a Sphere"); case CR_ICOSAHEDRON: return QString("Icosahedron"); case CR_DODECAHEDRON: return QString("Dodecahedron"); case CR_OCTAHEDRON: return QString("Octahedron"); @@ -68,7 +70,7 @@ QString FilterCreate::filterInfo(FilterIDType filterId) const case CR_ANNULUS : return QString("Create an Annulus, e.g. a flat region bounded by two concentric circles"); case CR_SPHERE: return QString("Create a Sphere"); case CR_SPHERE_CAP: return QString("Create a Sphere Cap subtended by a cone of given angle"); - case CR_RANDOM_SPHERE: return QString("Create a random spherical point cloud"); + case CR_RANDOM_SPHERE: return QString("Create a spherical point cloud, it can be random or regularly distributed."); case CR_ICOSAHEDRON: return QString("Create an Icosahedron"); case CR_DODECAHEDRON: return QString("Create an Dodecahedron"); case CR_OCTAHEDRON: return QString("Create an Octahedron"); @@ -108,6 +110,7 @@ void FilterCreate::initParameterSet(QAction *action, MeshModel & m, RichParamete break; case CR_RANDOM_SPHERE : parlst.addParam(new RichInt("pointNum",100,"Point Num","Number of points (approximate).")); + parlst.addParam(new RichBool("randomFlag",true,"Random","If true the points are randomly generated using a Poisson Disk distribution. Otherwise the Dave Rusin's disco ball algorithm for the regular placement of points on a sphere is used.")); break; case CR_BOX : parlst.addParam(new RichFloat("size",1,"Scale factor","Scales the new mesh")); @@ -160,35 +163,44 @@ bool FilterCreate::applyFilter(QAction *filter, MeshDocument &md, RichParameterS break; } case CR_RANDOM_SPHERE: - { + { CMeshO tt; int pointNum = par.getInt("pointNum"); - int oversamplingFactor =100; - if(pointNum <= 100) oversamplingFactor = 1000; - if(pointNum >= 10000) oversamplingFactor = 50; - if(pointNum >= 100000) oversamplingFactor = 20; + bool randomFlag=par.getBool("randomFlag"); - math::MarsenneTwisterRNG rng; - tri::Allocator::AddVertices(tt,pointNum*50); - for(CMeshO::VertexIterator vi=tt.vert.begin();vi!=tt.vert.end();++vi) - vi->P()=math::GeneratePointOnUnitSphereUniform(rng); - tri::UpdateBounding::Box(tt); - - const float SphereArea = 4*M_PI; - float poissonRadius = 2.0*sqrt((SphereArea / float(pointNum*2))/M_PI); - - std::vector poissonSamples; - tri::TrivialSampler pdSampler(poissonSamples); - tri::SurfaceSampling >::PoissonDiskParam pp; - - tri::SurfaceSampling >::PoissonDiskPruning(pdSampler, tt, poissonRadius, pp); - m->cm.Clear(); - tri::Allocator::AddVertices(m->cm,poissonSamples.size()); - for(size_t i=0;icm.vert[i].P()=poissonSamples[i]; - m->cm.vert[i].N()=m->cm.vert[i].P(); + int oversamplingFactor =100; + if(pointNum <= 100) oversamplingFactor = 1000; + if(pointNum >= 10000) oversamplingFactor = 50; + if(pointNum >= 100000) oversamplingFactor = 20; + + math::MarsenneTwisterRNG rng; + tri::Allocator::AddVertices(tt,pointNum*50); + for(CMeshO::VertexIterator vi=tt.vert.begin();vi!=tt.vert.end();++vi) + vi->P()=math::GeneratePointOnUnitSphereUniform(rng); + tri::UpdateBounding::Box(tt); + + const float SphereArea = 4*M_PI; + float poissonRadius = 2.0*sqrt((SphereArea / float(pointNum*2))/M_PI); + + std::vector poissonSamples; + tri::TrivialSampler pdSampler(poissonSamples); + tri::SurfaceSampling >::PoissonDiskParam pp; + + tri::SurfaceSampling >::PoissonDiskPruning(pdSampler, tt, poissonRadius, pp); + m->cm.Clear(); + for(size_t i=0;i::AddVertex(m->cm,poissonSamples[i],poissonSamples[i]); + } + else + { + std::vector regularSamples; + GenNormal::Regular(pointNum,regularSamples); + m->cm.Clear(); + for(size_t i=0;i::AddVertex(m->cm,regularSamples[i],regularSamples[i]); } } break;