diff --git a/src/fgt/filter_qhull/filter_qhull.cpp b/src/fgt/filter_qhull/filter_qhull.cpp index afe3ede1a..14cce0f52 100644 --- a/src/fgt/filter_qhull/filter_qhull.cpp +++ b/src/fgt/filter_qhull/filter_qhull.cpp @@ -96,7 +96,7 @@ const QString QhullPlugin::filterInfo(FilterIDType filterId) case FP_QHULL_VORONOI_FILTERING : return QString("Compute mesh Voronoi filtering with Qhull library.
" "The filter reconstructs the mesh surface starting from its vertices through a double " "Delaunay triangulation.
The second one takes in input some Voronoi vertices too.
"); - case FP_QHULL_ALPHA_COMPLEX_AND_SHAPE: return QString("Calculate Alpha Shapes.
" + case FP_QHULL_ALPHA_COMPLEX_AND_SHAPE: return QString("Calculate Alpha Shape.
" "The Alpha Shape is the boundary of the alpha complex, that is a subcomplex of the Delaunay triangulation.
" "For a given value of 'alpha', the alpha complex includes all the simplices in the Delaunay " "triangulation which have an empty circumsphere with radius equal or smaller than 'alpha'"); @@ -172,7 +172,7 @@ void QhullPlugin::initParameterSet(QAction *action,MeshModel &m, FilterParameter "ViewPoint", "if UseCamera is true, this value is ignored"); - parlst.addBool("convex_hull",false,"Show Convex Hull of flipped points", "Show Convex Hull of the transformed point cloud"); + parlst.addBool("convex_hull",false,"Show Partial Convex Hull of flipped points", "Show Partial Convex Hull of the transformed point cloud"); break; } default : assert(0); @@ -380,7 +380,7 @@ bool QhullPlugin::applyFilter(QAction *filter, MeshDocument &md, FilterParameter if (m.hasDataMask(MeshModel::MM_VERTTEXCOORD)){ m.clearDataMask(MeshModel::MM_VERTTEXCOORD); } - + int dim= 3; /* dimension of points */ int numpoints= m.cm.vn; /* number of mesh vertices */ @@ -402,6 +402,11 @@ bool QhullPlugin::applyFilter(QAction *filter, MeshDocument &md, FilterParameter MeshModel &pm =*md.addNewMesh(name); + if (!alphashape && !pm.hasDataMask(MeshModel::MM_FACEQUALITY)) + { + pm.updateDataMask(MeshModel::MM_FACEQUALITY); + } + bool result =compute_alpha_shapes(dim,numpoints,m,pm,alpha,alphashape); if(result){ @@ -412,16 +417,6 @@ bool QhullPlugin::applyFilter(QAction *filter, MeshDocument &md, FilterParameter Log(GLLogStream::FILTER,"Alpha = %f ",alpha); //m.cm.Clear(); - //Prova del 9 POI TOGLILA - if(vcg::tri::HasPerFaceAttribute(pm.cm,"Alpha") && pm.cm.fn>0){ - CMeshO::PerFaceAttributeHandle alphaHandle =tri::Allocator::GetPerFaceAttribute(pm.cm, "Alpha"); - CMeshO::FaceIterator fi =pm.cm.face.begin(); - //Una faccia a caso: la prima - double provaAlpha = alphaHandle[fi]; - Log(GLLogStream::FILTER,"ProvaRadius = %f ",provaAlpha); - } - //Fine prova del 9 - return true; } else @@ -457,7 +452,7 @@ bool QhullPlugin::applyFilter(QAction *filter, MeshDocument &md, FilterParameter viewpoint = m.cm.shot.GetViewPoint(); } - MeshModel &pm =*md.addNewMesh("Visibile Points"); + MeshModel &pm =*md.addNewMesh("CH Flipped Points"); if (m.hasDataMask(MeshModel::MM_WEDGTEXCOORD)){ m.clearDataMask(MeshModel::MM_WEDGTEXCOORD); diff --git a/src/fgt/filter_qhull/qhull_tools.cpp b/src/fgt/filter_qhull/qhull_tools.cpp index c13874e16..f2a3d2c42 100644 --- a/src/fgt/filter_qhull/qhull_tools.cpp +++ b/src/fgt/filter_qhull/qhull_tools.cpp @@ -44,11 +44,9 @@ using namespace vcg; #define TestMode 0 -//Internal prototype ALCUNI SONO INTUTILI POI TOGLILI +//Internal prototype coordT *qh_readpointsFromMesh(int *numpoints, int *dimension, MeshModel &m); -bool test(facetT* facet, ridgeT* triangle ,double alpha); -void addDelaunay (coordT *points, int numpoints, int numnew, int dim); -coordT pointdist(pointT *point1, pointT *point2, int dim); +double calculate_circumradius(pointT* p0,pointT* p1,pointT* p2, int dim); /***************************************************************************/ @@ -465,7 +463,8 @@ bool compute_voronoi(int dim, int numpoints, MeshModel &m, MeshModel &pm) alphashape --> true to calculate alpha shape, false alpha complex compute_alpha_shapes(int dim, int numpoints, MeshModel &m, MeshModel &pm, double alpha, bool alphashape) - build alpha complex ora alpha shapes from a set of vertices of a mesh. + build alpha complex or alpha shapes from a set of vertices of a mesh. + Insert the minimum value of alpha (radius of the circumsphere) in attribute quality foreach face. The Alpha Shape is the boundary of the alpha complex, that is a subcomplex of the Delaunay triangulation. For a given value of 'alpha', the alpha complex includes all the simplices in the Delaunay @@ -507,8 +506,6 @@ bool compute_alpha_shapes(int dim, int numpoints, MeshModel &m, MeshModel &pm, d tri::Allocator::AddVertices(pm.cm,convexNumVert); - CMeshO::PerFaceAttributeHandle alphaHandle = vcg::tri::Allocator::AddPerFaceAttribute(pm.cm,std::string("Alpha")); - /*ivp length is 'qh num_vertices' because each vertex is accessed through its ID whose range is 0<=qh_pointid(vertex->point)::VertexPointer> ivp(qh num_vertices); @@ -537,13 +534,7 @@ bool compute_alpha_shapes(int dim, int numpoints, MeshModel &m, MeshModel &pm, d //the distance between the circumcenter and a vertex of the facet vertexT* vertex = (vertexT *)(facet->vertices->e[0].p); double* center = facet->center; - double px = (*vertex).point[0]; - double qx = *center; - double py = (*vertex).point[1]; - double qy = *center++; - double pz = (*vertex).point[2]; - double qz = *center++; - double radius = sqrt(pow(px-qx,2)+pow(py-qy,2)+pow(pz-qz,2)); + double radius = qh_pointdist(vertex->point,center,dim); if (radius>alpha) // if the facet is not good consider the ridges { @@ -564,13 +555,7 @@ bool compute_alpha_shapes(int dim, int numpoints, MeshModel &m, MeshModel &pm, d pointT* p1 = ((vertexT*) (ridge->vertices->e[1].p))->point; pointT* p2 = ((vertexT*) (ridge->vertices->e[2].p))->point; - coordT a = qh_pointdist(p0,p1,3); - coordT b = qh_pointdist(p1,p2,3); - coordT c = qh_pointdist(p2,p0,3); - - coordT sum =(a + b + c)*0.5; - coordT area = sum*(a+b-sum)*(a+c-sum)*(b+c-sum); - radius = (double) (a*b*c)/(4*sqrt(area)); + radius = calculate_circumradius(p0,p1,p2, dim); if(radius <=alpha){ goodTriangles++; @@ -578,13 +563,16 @@ bool compute_alpha_shapes(int dim, int numpoints, MeshModel &m, MeshModel &pm, d if(!alphashape){ tri::Allocator::FaceIterator fi=tri::Allocator::AddFaces(pm.cm,1); ridgesCount++; - alphaHandle[fi] = radius; + + //Store di circumradius of the face in face quality + (*fi).Q() = radius; + int vertex_n, vertex_i; FOREACHvertex_i_(ridge->vertices) (*fi).V(vertex_i)= ivp[qh_pointid(vertex->point)]; } else - //if calculating alpha shapes, save the triangle for subsequent filtering + //if calculating alpha shape, save the triangle for subsequent filtering qh_setappend(&set, ridge); } } @@ -612,7 +600,14 @@ bool compute_alpha_shapes(int dim, int numpoints, MeshModel &m, MeshModel &pm, d //if calculating alphacomplex build mesh. It needs no filtering if(!alphashape){ tri::Allocator::FaceIterator fi=tri::Allocator::AddFaces(pm.cm,1); - alphaHandle[fi] = radius; //CORREGGI CON IL RAGGIO DELLA CIRCOSFERA + + //Store di circumradius of the face in face quality + pointT* p0 = ((vertexT*) (ridge->vertices->e[0].p))->point; + pointT* p1 = ((vertexT*) (ridge->vertices->e[1].p))->point; + pointT* p2 = ((vertexT*) (ridge->vertices->e[2].p))->point; + radius = calculate_circumradius(p0,p1,p2, dim); + (*fi).Q() = radius; + ridgesCount++; int vertex_n, vertex_i; FOREACHvertex_i_(ridge->vertices) @@ -665,7 +660,7 @@ bool compute_alpha_shapes(int dim, int numpoints, MeshModel &m, MeshModel &pm, d pm --> new mesh that is the convex hull of the flipped points, if convex_hull is true viewpoint -> the viewpoint threshold -> bounds the radius oh the sphere used to select visible points - convex_hull --> true if you want to show the Convex Hull of the transformed point cloud + convex_hull --> true if you want to show the partial Convex Hull of the transformed points cloud false otherwise bool visible_points(int dim, int numpoints, MeshModel &m, MeshModel &pm) @@ -764,6 +759,7 @@ int visible_points(int dim, int numpoints, MeshModel &m,MeshModel &pm,Point3f vi int i=0; FORALLvertices{ + //Do not add the viewpoint if ((*vertex).point && qh_pointid(vertex->point)point)]->SetS(); @@ -780,7 +776,7 @@ int visible_points(int dim, int numpoints, MeshModel &m,MeshModel &pm,Point3f vi vcg::tri::UpdateColor::VertexSelected(m.cm); if(convex_hull){ - //Add the faces of the convex_hull to the new mesh + //Add to the new mesh only the faces of the convex hull whose vertices aren't the viewpoint facetT *facet; FORALLfacet_(qh facet_list){ vertexT *vertex; @@ -842,6 +838,23 @@ coordT *qh_readpointsFromMesh(int *numpoints, int *dimension, MeshModel &m) { return(points); } +/* + double calculate_circumradius(pointT* p0,pointT* p1,pointT* p2, int dim) + calculate the radius of the circumference passing through p0, p1, p2. +*/ + + +double calculate_circumradius(pointT* p0,pointT* p1,pointT* p2, int dim){ + coordT a = qh_pointdist(p0,p1,dim); + coordT b = qh_pointdist(p1,p2,dim); + coordT c = qh_pointdist(p2,p0,dim); + + coordT sum =(a + b + c)*0.5; + coordT area = sum*(a+b-sum)*(a+c-sum)*(b+c-sum); + return (double) (a*b*c)/(4*sqrt(area)); +} + +//-------------------------------------------------------------------------------- bool test(facetT* facet, ridgeT* triangle ,double alpha){ vertexT* vertex = (vertexT *)(facet->vertices->e[0].p);