From 24675fee0bbfb0ec30ea042dc6a8d28b360efd80 Mon Sep 17 00:00:00 2001 From: Paolo Cignoni cignoni Date: Thu, 15 May 2014 10:54:21 +0000 Subject: [PATCH] Added Sphere Cap to the Primitives --- .../filter_create/filter_create.cpp | 94 +++++++++++-------- .../filter_create/filter_create.h | 39 +++++--- 2 files changed, 83 insertions(+), 50 deletions(-) diff --git a/src/meshlabplugins/filter_create/filter_create.cpp b/src/meshlabplugins/filter_create/filter_create.cpp index 42743d22b..6f721d22e 100644 --- a/src/meshlabplugins/filter_create/filter_create.cpp +++ b/src/meshlabplugins/filter_create/filter_create.cpp @@ -23,6 +23,9 @@ #include "filter_create.h" #include #include +#include +using namespace vcg; +using namespace tri; // Constructor usually performs only two simple tasks of filling the two lists // - typeList: with all the possible id of the filtering actions @@ -30,7 +33,9 @@ FilterCreate::FilterCreate() { - typeList <" "Admitted values are in the range 0 (an icosahedron) to 8 (a 1.3 MegaTris approximation of a sphere)")); break; + + case CR_SPHERE_CAP : + parlst.addParam(new RichFloat("angle",60,"Angle","Angle of the cone subtending the cap. It must be < 180")); + parlst.addParam(new RichInt("subdiv",3,"Subdiv. Level","Number of the recursive subdivision of the surface. Default is 3 (a sphere approximation composed by 1280 faces).
" + "Admitted values are in the range 0 (an icosahedron) to 8 (a 1.3 MegaTris approximation of a sphere)")); + break; case CR_ANNULUS : parlst.addParam(new RichFloat("internalRadius",0.5f,"Internal Radius","Internal Radius of the annulus")); parlst.addParam(new RichFloat("externalRadius",1.0f,"External Radius","Externale Radius of the annulus")); @@ -116,25 +129,25 @@ void FilterCreate::initParameterSet(QAction *action, MeshModel & /*m*/, RichPara } // The Real Core Function doing the actual mesh processing. -bool FilterCreate::applyFilter(QAction *filter, MeshDocument &md, RichParameterSet & par, vcg::CallBackPos * /*cb*/) +bool FilterCreate::applyFilter(QAction *filter, MeshDocument &md, RichParameterSet & par, CallBackPos * /*cb*/) { MeshModel* m=md.addNewMesh("",this->filterName(ID(filter))); switch(ID(filter)) { case CR_TETRAHEDRON : - vcg::tri::Tetrahedron(m->cm); + tri::Tetrahedron(m->cm); break; case CR_ICOSAHEDRON: - vcg::tri::Icosahedron(m->cm); + tri::Icosahedron(m->cm); break; case CR_DODECAHEDRON: - vcg::tri::Dodecahedron(m->cm); + tri::Dodecahedron(m->cm); m->updateDataMask(MeshModel::MM_POLYGONAL); break; case CR_OCTAHEDRON: - vcg::tri::Octahedron(m->cm); + tri::Octahedron(m->cm); break; case CR_ANNULUS: - vcg::tri::Annulus(m->cm,par.getFloat("internalRadius"), + tri::Annulus(m->cm,par.getFloat("internalRadius"), par.getFloat("externalRadius"),par.getInt("sides")); break; case CR_TORUS: @@ -143,7 +156,7 @@ bool FilterCreate::applyFilter(QAction *filter, MeshDocument &md, RichParameterS float vRadius=par.getFloat("vRadius"); int hSubdiv=par.getInt("hSubdiv"); int vSubdiv=par.getInt("vSubdiv"); - vcg::tri::Torus(m->cm,hRadius,vRadius,hSubdiv,vSubdiv); + tri::Torus(m->cm,hRadius,vRadius,hSubdiv,vSubdiv); break; } case CR_RANDOM_SPHERE: @@ -156,22 +169,22 @@ bool FilterCreate::applyFilter(QAction *filter, MeshDocument &md, RichParameterS if(pointNum >= 10000) oversamplingFactor = 50; if(pointNum >= 100000) oversamplingFactor = 20; - vcg::math::MarsenneTwisterRNG rng; - vcg::tri::Allocator::AddVertices(tt,pointNum*50); + math::MarsenneTwisterRNG rng; + tri::Allocator::AddVertices(tt,pointNum*50); for(CMeshO::VertexIterator vi=tt.vert.begin();vi!=tt.vert.end();++vi) - vi->P()=vcg::math::GeneratePointOnUnitSphereUniform(rng); - vcg::tri::UpdateBounding::Box(tt); + 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; - vcg::tri::TrivialSampler pdSampler(poissonSamples); - vcg::tri::SurfaceSampling >::PoissonDiskParam pp; + std::vector poissonSamples; + tri::TrivialSampler pdSampler(poissonSamples); + tri::SurfaceSampling >::PoissonDiskParam pp; - vcg::tri::SurfaceSampling >::PoissonDiskPruning(pdSampler, tt, poissonRadius, pp); + tri::SurfaceSampling >::PoissonDiskPruning(pdSampler, tt, poissonRadius, pp); m->cm.Clear(); - vcg::tri::Allocator::AddVertices(m->cm,poissonSamples.size()); + tri::Allocator::AddVertices(m->cm,poissonSamples.size()); for(size_t i=0;icm.vert[i].P()=poissonSamples[i]; @@ -179,26 +192,32 @@ bool FilterCreate::applyFilter(QAction *filter, MeshDocument &md, RichParameterS } } break; + case CR_SPHERE_CAP: + { + int rec = par.getInt("subdiv"); + const float angleDeg = par.getFloat("angle"); + m->updateDataMask(MeshModel::MM_FACEFACETOPO); + tri::UpdateTopology::FaceFace(m->cm); + tri::SphericalCap(m->cm,math::ToRad(angleDeg),rec); + } break; + case CR_SPHERE: { int rec = par.getInt("subdiv"); float radius = par.getFloat("radius"); m->cm.face.EnableFFAdjacency(); m->updateDataMask(MeshModel::MM_FACEFACETOPO); - assert(vcg::tri::HasPerVertexTexCoord(m->cm) == false); - vcg::tri::Sphere(m->cm,rec); - - for(CMeshO::VertexIterator vi = m->cm.vert.begin();vi!= m->cm.vert.end();++vi) - vi->P()=vi->P()*radius; - - break; - } - case CR_BOX: - { - float sz=par.getFloat("size"); - vcg::Box3f b(vcg::Point3f(1,1,1)*(-sz/2),vcg::Point3f(1,1,1)*(sz/2)); - vcg::tri::Box(m->cm,b); - m->updateDataMask(MeshModel::MM_POLYGONAL); + assert(tri::HasPerVertexTexCoord(m->cm) == false); + tri::Sphere(m->cm,rec); + tri::UpdatePosition::Scale(m->cm,radius); + break; + } + case CR_BOX: + { + float sz=par.getFloat("size"); + Box3f b(Point3f(1,1,1)*(-sz/2),Point3f(1,1,1)*(sz/2)); + tri::Box(m->cm,b); + m->updateDataMask(MeshModel::MM_POLYGONAL); break; } @@ -207,11 +226,11 @@ bool FilterCreate::applyFilter(QAction *filter, MeshDocument &md, RichParameterS float r1=par.getFloat("r1"); float h=par.getFloat("h"); int subdiv=par.getInt("subdiv"); - vcg::tri::Cone(m->cm,r0,r1,h,subdiv); + tri::Cone(m->cm,r0,r1,h,subdiv); break; } - vcg::tri::UpdateBounding::Box(m->cm); - vcg::tri::UpdateNormal::PerVertexNormalizedPerFaceNormalized(m->cm); + tri::UpdateBounding::Box(m->cm); + tri::UpdateNormal::PerVertexNormalizedPerFaceNormalized(m->cm); return true; } @@ -219,12 +238,12 @@ bool FilterCreate::applyFilter(QAction *filter, MeshDocument &md, RichParameterS { switch(ID(a)) { - case CR_BOX: case CR_TETRAHEDRON: case CR_ICOSAHEDRON: case CR_DODECAHEDRON: case CR_SPHERE: + case CR_SPHERE_CAP: case CR_ANNULUS: case CR_RANDOM_SPHERE: case CR_OCTAHEDRON: @@ -244,6 +263,7 @@ QString FilterCreate::filterScriptFunctionName( FilterIDType filterID ) case CR_BOX : return QString("box"); case CR_ANNULUS : return QString("annulus"); case CR_SPHERE: return QString("sphere"); + case CR_SPHERE_CAP: return QString("spherecap"); case CR_RANDOM_SPHERE: return QString("randomsphere"); case CR_ICOSAHEDRON: return QString("icosahedron"); case CR_DODECAHEDRON: return QString("dodecahedron"); diff --git a/src/meshlabplugins/filter_create/filter_create.h b/src/meshlabplugins/filter_create/filter_create.h index 0cb2c964e..28a7b87b1 100644 --- a/src/meshlabplugins/filter_create/filter_create.h +++ b/src/meshlabplugins/filter_create/filter_create.h @@ -27,22 +27,35 @@ class FilterCreate : public QObject, public MeshFilterInterface { - Q_OBJECT - MESHLAB_PLUGIN_IID_EXPORTER(MESH_FILTER_INTERFACE_IID) - Q_INTERFACES(MeshFilterInterface) + Q_OBJECT + MESHLAB_PLUGIN_IID_EXPORTER(MESH_FILTER_INTERFACE_IID) + Q_INTERFACES(MeshFilterInterface) -public: - enum { CR_BOX, CR_ANNULUS, CR_SPHERE, CR_RANDOM_SPHERE, CR_ICOSAHEDRON,CR_DODECAHEDRON, CR_TETRAHEDRON, CR_OCTAHEDRON, CR_CONE, CR_TORUS } ; + public: + enum { + CR_BOX, + CR_ANNULUS, + CR_SPHERE, + CR_SPHERE_CAP, + CR_RANDOM_SPHERE, + CR_ICOSAHEDRON, + CR_DODECAHEDRON, + CR_TETRAHEDRON, + CR_OCTAHEDRON, + CR_CONE, + CR_TORUS, - FilterCreate(); + } ; - QString filterName(FilterIDType filter) const; - QString filterInfo(FilterIDType filter) const; - FilterClass getClass(QAction *); - void initParameterSet(QAction *,MeshModel &/*m*/, RichParameterSet & /*parent*/); - bool applyFilter(QAction *filter, MeshDocument &md, RichParameterSet & /*parent*/, vcg::CallBackPos * cb) ; - QString filterScriptFunctionName(FilterIDType filterID); - QString pluginName(void) const { return "FilterCreate"; } + FilterCreate(); + + QString filterName(FilterIDType filter) const; + QString filterInfo(FilterIDType filter) const; + FilterClass getClass(QAction *); + void initParameterSet(QAction *,MeshModel &/*m*/, RichParameterSet & /*parent*/); + bool applyFilter(QAction *filter, MeshDocument &md, RichParameterSet & /*parent*/, vcg::CallBackPos * cb) ; + QString filterScriptFunctionName(FilterIDType filterID); + QString pluginName(void) const { return "FilterCreate"; } }; #endif