mirror of
https://github.com/lucaspalomodevelop/meshlab.git
synced 2026-03-19 02:54:36 +00:00
Added convex hull of non flipped points in visible points
This commit is contained in:
parent
53e73d1252
commit
ada5e9fb2e
@ -46,8 +46,6 @@
|
||||
using namespace std;
|
||||
using namespace vcg;
|
||||
|
||||
//Internal prototype
|
||||
bool create_mesh_convex_hull(MeshDocument &md,MeshModel &m,FilterParameterSet & par);
|
||||
|
||||
// Constructor usually performs only two simple tasks of filling the two lists
|
||||
// - typeList: with all the possible id of the filtering actions
|
||||
@ -110,7 +108,7 @@ const QString QhullPlugin::filterInfo(FilterIDType filterId)
|
||||
case FP_QHULL_VISIBLE_POINTS: return QString("Select the <b>visible points</b> in a point cloud, as viewed from a given viewpoint.<br>"
|
||||
"It uses the Qhull library (http://www.qhull.org/ <br><br>"
|
||||
"The algorithm used (Katz, Tal and Basri 2007) determines visibility without reconstructing a surface or estimating normals."
|
||||
"The visible points are those that corresponds to the ones that reside on the convex hull of a transformed point cloud.");
|
||||
"The visible points are those that correspond to the ones that reside on the convex hull of a transformed point cloud.");
|
||||
default : assert(0);
|
||||
}
|
||||
return QString("Error: Unknown Filter");
|
||||
@ -156,7 +154,7 @@ void QhullPlugin::initParameterSet(QAction *action,MeshModel &m, FilterParameter
|
||||
}
|
||||
case FP_QHULL_VORONOI_FILTERING :
|
||||
{
|
||||
parlst.addDynamicFloat("threshold",100.0f, 100.0f, 2000.0f,MeshModel::MM_NONE,"threshold ","????.");
|
||||
parlst.addDynamicFloat("threshold",0.0f, 0.0f, 2000.0f,MeshModel::MM_NONE,"threshold ","????.");
|
||||
break;
|
||||
}
|
||||
case FP_QHULL_ALPHA_COMPLEX_AND_SHAPE:
|
||||
@ -185,7 +183,7 @@ void QhullPlugin::initParameterSet(QAction *action,MeshModel &m, FilterParameter
|
||||
"if UseCamera is true, this value is ignored");
|
||||
|
||||
parlst.addBool("convex_hullFP",false,"Show Partial Convex Hull of flipped points", "Show Partial Convex Hull of the transformed point cloud");
|
||||
parlst.addBool("convex_hullNFP",false,"Show the Convex Hull of the given points", "Show the Convex Hull of the given points");
|
||||
parlst.addBool("convex_hullNFP",false,"Show the Convex Hull of the non flipped points", "Show the Convex Hull of the given points");
|
||||
parlst.addBool("reorient", false,"Re-orient all faces of the CH coherentely","Re-orient all faces of the CH coherentely."
|
||||
"If no Convex Hulls are selected , this value is ignored");
|
||||
break;
|
||||
@ -203,13 +201,93 @@ bool QhullPlugin::applyFilter(QAction *filter, MeshDocument &md, FilterParameter
|
||||
case FP_QHULL_CONVEX_HULL :
|
||||
{
|
||||
MeshModel &m=*md.mm();
|
||||
bool result= create_mesh_convex_hull(md,m,par);
|
||||
|
||||
if(result){
|
||||
Log(GLLogStream::FILTER,"Successfully created a mesh of %i vert and %i faces",m.cm.vn,m.cm.fn);
|
||||
return true;
|
||||
MeshModel &pm =*md.addNewMesh("Convex Hull");
|
||||
|
||||
if (m.hasDataMask(MeshModel::MM_WEDGTEXCOORD)){
|
||||
m.clearDataMask(MeshModel::MM_WEDGTEXCOORD);
|
||||
}
|
||||
else return false;
|
||||
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 */
|
||||
|
||||
//facet_list contains the convex hull
|
||||
//facet_list contains simplicial (triangulated) facets.
|
||||
//The convex hull of a set of points is the smallest convex set containing the points.
|
||||
|
||||
facetT *facet_list = compute_convex_hull(dim,numpoints,m);
|
||||
|
||||
if(facet_list!=NULL){
|
||||
|
||||
int convexNumFaces = qh num_facets;
|
||||
int convexNumVert = qh_setsize(qh_facetvertices (facet_list, NULL, false));
|
||||
assert( qh num_vertices == convexNumVert);
|
||||
|
||||
tri::Allocator<CMeshO>::AddVertices(pm.cm,convexNumVert);
|
||||
tri::Allocator<CMeshO>::AddFaces(pm.cm,convexNumFaces);
|
||||
|
||||
|
||||
/*ivp length is 'numpoints' because each vertex is accessed through its ID whose range is
|
||||
0<=qh_pointid(vertex->point)<numpoints. qh num_vertices is < numpoints*/
|
||||
vector<tri::Allocator<CMeshO>::VertexPointer> ivp(numpoints);
|
||||
vertexT *vertex;
|
||||
int i=0;
|
||||
FORALLvertices{
|
||||
if ((*vertex).point){
|
||||
pm.cm.vert[i].P()[0] = (*vertex).point[0];
|
||||
pm.cm.vert[i].P()[1] = (*vertex).point[1];
|
||||
pm.cm.vert[i].P()[2] = (*vertex).point[2];
|
||||
ivp[qh_pointid(vertex->point)] = &pm.cm.vert[i];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
facetT *facet;
|
||||
i=0;
|
||||
FORALLfacet_(facet_list){
|
||||
vertexT *vertex;
|
||||
int vertex_n, vertex_i;
|
||||
FOREACHvertex_i_((*facet).vertices){
|
||||
pm.cm.face[i].V(vertex_i)= ivp[qh_pointid(vertex->point)];
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
assert( pm.cm.fn == convexNumFaces);
|
||||
//m.cm.Clear();
|
||||
|
||||
//Re-orient normals
|
||||
bool reorient= par.getBool("reorient");
|
||||
if (reorient){
|
||||
pm.updateDataMask(MeshModel::MM_FACEFACETOPO);
|
||||
bool oriented, orientable;
|
||||
|
||||
tri::Clean<CMeshO>::IsOrientedMesh(pm.cm, oriented,orientable);
|
||||
vcg::tri::UpdateTopology<CMeshO>::FaceFace(pm.cm);
|
||||
vcg::tri::UpdateTopology<CMeshO>::TestFaceFace(pm.cm);
|
||||
pm.clearDataMask(MeshModel::MM_FACEFACETOPO);
|
||||
tri::UpdateSelection<CMeshO>::ClearFace(pm.cm);
|
||||
}
|
||||
|
||||
vcg::tri::UpdateBounding<CMeshO>::Box(pm.cm);
|
||||
vcg::tri::UpdateNormals<CMeshO>::PerVertexNormalizedPerFace(pm.cm);
|
||||
Log(GLLogStream::FILTER,"Successfully created a mesh of %i vert and %i faces",m.cm.vn,m.cm.fn);
|
||||
|
||||
int curlong, totlong; /* memory remaining after qh_memfreeshort */
|
||||
qh_freeqhull(!qh_ALL);
|
||||
qh_memfreeshort (&curlong, &totlong);
|
||||
if (curlong || totlong)
|
||||
fprintf (stderr, "qhull internal warning (main): did not free %d bytes of long memory (%d pieces)\n",
|
||||
totlong, curlong);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
}
|
||||
case FP_QHULL_DELAUNAY_TRIANGULATION:
|
||||
{
|
||||
@ -407,7 +485,7 @@ bool QhullPlugin::applyFilter(QAction *filter, MeshDocument &md, FilterParameter
|
||||
viewpoint = m.cm.shot.GetViewPoint();
|
||||
}
|
||||
|
||||
MeshModel &pm =*md.addNewMesh("CH Flipped Points");
|
||||
MeshModel &pm =*md.addNewMesh("CH Flipped Points");
|
||||
|
||||
if (pm.hasDataMask(MeshModel::MM_WEDGTEXCOORD)){
|
||||
pm.clearDataMask(MeshModel::MM_WEDGTEXCOORD);
|
||||
@ -416,8 +494,19 @@ bool QhullPlugin::applyFilter(QAction *filter, MeshDocument &md, FilterParameter
|
||||
pm.clearDataMask(MeshModel::MM_VERTTEXCOORD);
|
||||
}
|
||||
|
||||
MeshModel &pm2 =*md.addNewMesh("CH Non Flipped Points");
|
||||
|
||||
if (pm2.hasDataMask(MeshModel::MM_WEDGTEXCOORD)){
|
||||
pm2.clearDataMask(MeshModel::MM_WEDGTEXCOORD);
|
||||
}
|
||||
if (pm2.hasDataMask(MeshModel::MM_VERTTEXCOORD)){
|
||||
pm2.clearDataMask(MeshModel::MM_VERTTEXCOORD);
|
||||
}
|
||||
|
||||
bool convex_hullFP = par.getBool("convex_hullFP");
|
||||
int result = visible_points(dim,numpoints,m,pm,viewpoint,threshold,convex_hullFP );
|
||||
bool convex_hullNFP = par.getBool("convex_hullNFP");
|
||||
|
||||
int result = visible_points(dim,numpoints,m,pm,pm2,viewpoint,threshold,convex_hullFP,convex_hullNFP);
|
||||
|
||||
if(!convex_hullFP)
|
||||
md.delMesh(&pm);
|
||||
@ -439,11 +528,31 @@ bool QhullPlugin::applyFilter(QAction *filter, MeshDocument &md, FilterParameter
|
||||
Log(GLLogStream::FILTER,"Successfully created a mesh of %i vert and %i faces",pm.cm.vn,pm.cm.fn);
|
||||
}
|
||||
|
||||
bool convex_hullNFP = par.getBool("convex_hullNFP");
|
||||
if(convex_hullNFP){
|
||||
bool result =create_mesh_convex_hull(md,m,par);
|
||||
|
||||
if(!convex_hullNFP){
|
||||
/*bool result =create_mesh_convex_hull(md,m,par);
|
||||
if(result)
|
||||
Log(GLLogStream::FILTER,"Successfully created a mesh of %i vert and %i faces",(*md.mm()).cm.vn,(*md.mm()).cm.fn);
|
||||
*/
|
||||
md.delMesh(&pm2);
|
||||
}
|
||||
else{
|
||||
//Re-orient normals
|
||||
bool reorient= par.getBool("reorient");
|
||||
if (reorient){
|
||||
pm2.updateDataMask(MeshModel::MM_FACEFACETOPO);
|
||||
bool oriented,orientable;
|
||||
|
||||
tri::Clean<CMeshO>::IsOrientedMesh(pm2.cm, oriented,orientable);
|
||||
vcg::tri::UpdateTopology<CMeshO>::FaceFace(pm2.cm);
|
||||
vcg::tri::UpdateTopology<CMeshO>::TestFaceFace(pm2.cm);
|
||||
pm2.clearDataMask(MeshModel::MM_FACEFACETOPO);
|
||||
tri::UpdateSelection<CMeshO>::ClearFace(pm2.cm);
|
||||
}
|
||||
|
||||
vcg::tri::UpdateBounding<CMeshO>::Box(pm2.cm);
|
||||
vcg::tri::UpdateNormals<CMeshO>::PerVertexNormalizedPerFace(pm2.cm);
|
||||
Log(GLLogStream::FILTER,"Successfully created a mesh of %i vert and %i faces",pm2.cm.vn,pm2.cm.fn);
|
||||
}
|
||||
|
||||
if(result>=0){
|
||||
@ -455,93 +564,4 @@ bool QhullPlugin::applyFilter(QAction *filter, MeshDocument &md, FilterParameter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool create_mesh_convex_hull(MeshDocument &md,MeshModel &m,FilterParameterSet & par){
|
||||
MeshModel &pm =*md.addNewMesh("Convex Hull");
|
||||
|
||||
if (m.hasDataMask(MeshModel::MM_WEDGTEXCOORD)){
|
||||
m.clearDataMask(MeshModel::MM_WEDGTEXCOORD);
|
||||
}
|
||||
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 */
|
||||
|
||||
//facet_list contains the convex hull
|
||||
//facet_list contains simplicial (triangulated) facets.
|
||||
//The convex hull of a set of points is the smallest convex set containing the points.
|
||||
|
||||
facetT *facet_list = compute_convex_hull(dim,numpoints,m);
|
||||
|
||||
if(facet_list!=NULL){
|
||||
|
||||
int convexNumFaces = qh num_facets;
|
||||
int convexNumVert = qh_setsize(qh_facetvertices (facet_list, NULL, false));
|
||||
assert( qh num_vertices == convexNumVert);
|
||||
|
||||
tri::Allocator<CMeshO>::AddVertices(pm.cm,convexNumVert);
|
||||
tri::Allocator<CMeshO>::AddFaces(pm.cm,convexNumFaces);
|
||||
|
||||
|
||||
/*ivp length is 'numpoints' because each vertex is accessed through its ID whose range is
|
||||
0<=qh_pointid(vertex->point)<numpoints. qh num_vertices is < numpoints*/
|
||||
vector<tri::Allocator<CMeshO>::VertexPointer> ivp(numpoints);
|
||||
vertexT *vertex;
|
||||
int i=0;
|
||||
FORALLvertices{
|
||||
if ((*vertex).point){
|
||||
pm.cm.vert[i].P()[0] = (*vertex).point[0];
|
||||
pm.cm.vert[i].P()[1] = (*vertex).point[1];
|
||||
pm.cm.vert[i].P()[2] = (*vertex).point[2];
|
||||
ivp[qh_pointid(vertex->point)] = &pm.cm.vert[i];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
facetT *facet;
|
||||
i=0;
|
||||
FORALLfacet_(facet_list){
|
||||
vertexT *vertex;
|
||||
int vertex_n, vertex_i;
|
||||
FOREACHvertex_i_((*facet).vertices){
|
||||
pm.cm.face[i].V(vertex_i)= ivp[qh_pointid(vertex->point)];
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
assert( pm.cm.fn == convexNumFaces);
|
||||
//m.cm.Clear();
|
||||
|
||||
//Re-orient normals
|
||||
bool reorient= par.getBool("reorient");
|
||||
if (reorient){
|
||||
pm.updateDataMask(MeshModel::MM_FACEFACETOPO);
|
||||
bool oriented, orientable;
|
||||
|
||||
tri::Clean<CMeshO>::IsOrientedMesh(pm.cm, oriented,orientable);
|
||||
vcg::tri::UpdateTopology<CMeshO>::FaceFace(pm.cm);
|
||||
vcg::tri::UpdateTopology<CMeshO>::TestFaceFace(pm.cm);
|
||||
pm.clearDataMask(MeshModel::MM_FACEFACETOPO);
|
||||
tri::UpdateSelection<CMeshO>::ClearFace(pm.cm);
|
||||
}
|
||||
|
||||
vcg::tri::UpdateBounding<CMeshO>::Box(pm.cm);
|
||||
vcg::tri::UpdateNormals<CMeshO>::PerVertexNormalizedPerFace(pm.cm);
|
||||
|
||||
int curlong, totlong; /* memory remaining after qh_memfreeshort */
|
||||
qh_freeqhull(!qh_ALL);
|
||||
qh_memfreeshort (&curlong, &totlong);
|
||||
if (curlong || totlong)
|
||||
fprintf (stderr, "qhull internal warning (main): did not free %d bytes of long memory (%d pieces)\n",
|
||||
totlong, curlong);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
Q_EXPORT_PLUGIN(QhullPlugin)
|
||||
|
||||
@ -159,7 +159,7 @@ facetT *compute_delaunay(int dim, int numpoints, MeshModel &m)
|
||||
numpoints --> number of points
|
||||
m --> original mesh
|
||||
pm --> new mesh
|
||||
threshold --> ??????????????????????????????????????
|
||||
threshold --> ??????????????????????????????????????PEZZA
|
||||
|
||||
compute_voronoi(int dim, int numpoints, MeshModel &m, MeshModel &pm)
|
||||
Compute a Voronoi filtering(Amenta and Bern 1998) with Qhull library (http://www.qhull.org/).
|
||||
@ -664,7 +664,7 @@ bool compute_alpha_shapes(int dim, int numpoints, MeshModel &m, MeshModel &pm, d
|
||||
numpoints --> number of points
|
||||
m --> original mesh
|
||||
pm --> new mesh that is the convex hull of the flipped points, if convex_hullFP is true
|
||||
pm2 --> new mesh that is the convex hull of the original points, if convex_hullNFP is true
|
||||
pm2 --> new mesh that is the convex hull of the non flipped points, if convex_hullNFP is true
|
||||
viewpoint -> the viewpoint
|
||||
threshold -> bounds the radius oh the sphere used to select visible points
|
||||
convex_hullFP --> true if you want to show the partial Convex Hull of the transformed points cloud
|
||||
@ -683,7 +683,7 @@ bool compute_alpha_shapes(int dim, int numpoints, MeshModel &m, MeshModel &pm, d
|
||||
-1 otherwise.
|
||||
*/
|
||||
|
||||
int visible_points(int dim, int numpoints, MeshModel &m, MeshModel &pm,vcg::Point3f viewpointP,float threshold,bool convex_hullFP){
|
||||
int visible_points(int dim, int numpoints, MeshModel &m, MeshModel &pm,MeshModel &pm2, vcg::Point3f viewpointP,float threshold,bool convex_hullFP,bool convex_hullNFP){
|
||||
boolT ismalloc= True; /* True if qhull should free points in qh_freeqhull() or reallocation */
|
||||
char flags[]= "qhull Tcv"; /* option flags for qhull, see qh_opt.htm */
|
||||
FILE *outfile= NULL; /* output from qh_produce_output()
|
||||
@ -758,6 +758,7 @@ int visible_points(int dim, int numpoints, MeshModel &m, MeshModel &pm,vcg::Poin
|
||||
/*ivp length is 'numpoints' because each vertex is accessed through its ID whose range is
|
||||
0<=qh_pointid(vertex->point)<numpoints. qh num_vertices is < numpoints*/
|
||||
vector<tri::Allocator<CMeshO>::VertexPointer> ivp_flipped(numpoints); //Vector of pointers to the flipped points
|
||||
vector<tri::Allocator<CMeshO>::VertexPointer> ivp_non_flipped(numpoints); //Vector of pointers to the non flipped points BRUTTOOOOO
|
||||
|
||||
vertexT *vertex;
|
||||
selected=qh num_vertices;
|
||||
@ -767,9 +768,14 @@ int visible_points(int dim, int numpoints, MeshModel &m, MeshModel &pm,vcg::Poin
|
||||
selected--;
|
||||
}
|
||||
|
||||
tri::Allocator<CMeshO>::AddVertices(pm.cm,selected);
|
||||
if(convex_hullFP)
|
||||
tri::Allocator<CMeshO>::AddVertices(pm.cm,selected);
|
||||
|
||||
if(convex_hullNFP)
|
||||
tri::Allocator<CMeshO>::AddVertices(pm2.cm,selected);
|
||||
|
||||
int i=0;
|
||||
int j=0;
|
||||
FORALLvertices{
|
||||
//Do not add the viewpoint
|
||||
if ((*vertex).point && qh_pointid(vertex->point)<numpoints){
|
||||
@ -783,6 +789,13 @@ int visible_points(int dim, int numpoints, MeshModel &m, MeshModel &pm,vcg::Poin
|
||||
ivp_flipped[qh_pointid(vertex->point)] = &pm.cm.vert[i];
|
||||
i++;
|
||||
}
|
||||
if(convex_hullNFP){ //Add non flipped points to the new mesh
|
||||
pm2.cm.vert[j].P()[0] = (*ivp[qh_pointid(vertex->point)]).P()[0];
|
||||
pm2.cm.vert[j].P()[1] = (*ivp[qh_pointid(vertex->point)]).P()[1];
|
||||
pm2.cm.vert[j].P()[2] = (*ivp[qh_pointid(vertex->point)]).P()[2];
|
||||
ivp_non_flipped[qh_pointid(vertex->point)] = &pm2.cm.vert[j];
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
vcg::tri::UpdateColor<CMeshO>::VertexSelected(m.cm);
|
||||
@ -804,6 +817,24 @@ int visible_points(int dim, int numpoints, MeshModel &m, MeshModel &pm,vcg::Poin
|
||||
}
|
||||
}
|
||||
}
|
||||
if(convex_hullNFP){
|
||||
//Add to the new mesh only the faces of the convex hull whose vertices aren't the viewpoint
|
||||
//Aggiusta
|
||||
facetT *facet;
|
||||
FORALLfacet_(qh facet_list){
|
||||
vertexT *vertex;
|
||||
int vertex_n, vertex_i;
|
||||
tri::Allocator<CMeshO>::FaceIterator fi=tri::Allocator<CMeshO>::AddFaces(pm2.cm,1);
|
||||
FOREACHvertex_i_((*facet).vertices){
|
||||
if(qh_pointid(vertex->point)<numpoints)
|
||||
(*fi).V(vertex_i)= ivp_non_flipped[qh_pointid(vertex->point)];
|
||||
else{
|
||||
tri::Allocator<CMeshO>::DeleteFace(pm2.cm,*fi);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int curlong, totlong; /* memory remaining after qh_memfreeshort */
|
||||
|
||||
@ -71,4 +71,4 @@ facetT *compute_convex_hull(int dim, int numpoints, MeshModel &m);
|
||||
facetT *compute_delaunay(int dim, int numpoints, MeshModel &m);
|
||||
bool compute_voronoi(int dim, int numpoints, MeshModel &m, MeshModel &pm,float threshold);
|
||||
bool compute_alpha_shapes(int dim, int numpoints, MeshModel &m, MeshModel &pm,double alpha, bool alphashape);
|
||||
int visible_points(int dim, int numpoints, MeshModel &m, MeshModel &pm,vcg::Point3f viewpoint,float threshold,bool convex_hullFP);
|
||||
int visible_points(int dim, int numpoints, MeshModel &m, MeshModel &pm,MeshModel &pm2, vcg::Point3f viewpointP,float threshold,bool convex_hullFP,bool convex_hullNFP);
|
||||
Loading…
x
Reference in New Issue
Block a user