mirror of
https://github.com/lucaspalomodevelop/meshlab.git
synced 2026-03-20 11:26:11 +00:00
vastly improved the overall robustness of the filter and the comman line version. Restored partially the debugging slicing fucntions. Better handling of point sets. Name filter changed according standard menu aware sorting rule
This commit is contained in:
parent
82baf654b6
commit
51267cc6a1
@ -47,7 +47,7 @@ PlyMCPlugin::PlyMCPlugin()
|
||||
QString PlyMCPlugin::filterName(FilterIDType filterId) const
|
||||
{
|
||||
switch(filterId) {
|
||||
case FP_PLYMC : return QString("VCG Reconstruction");
|
||||
case FP_PLYMC : return QString("Surface Reconstruction: VCG");
|
||||
default : assert(0);
|
||||
}
|
||||
}
|
||||
@ -60,7 +60,7 @@ PlyMCPlugin::PlyMCPlugin()
|
||||
case FP_PLYMC : return QString(
|
||||
"The surface reconstrction algorithm that have been used for a long time inside the ISTI-Visual Computer Lab."
|
||||
"It is mostly a variant of the Curless et al. e.g. a volumetric approach with some original weighting schemes,"
|
||||
"a different expansion rule, and another approach to hole filling through volume dilation.");
|
||||
"a different expansion rule, and another approach to hole filling through volume dilation/relaxations.");
|
||||
default : assert(0);
|
||||
}
|
||||
return QString("Unknown Filter");
|
||||
@ -97,14 +97,14 @@ void PlyMCPlugin::initParameterSet(QAction *action,MeshModel &m, RichParameterSe
|
||||
parlst.addParam( new RichBool("openResult",true,"Show Result","if not checked the result is only saved into the current directory"));
|
||||
parlst.addParam( new RichInt("smoothNum",1,"Volume Laplacian iter","the level of recursive splitting of the volume"));
|
||||
parlst.addParam( new RichInt("wideNum",3,"Widening","the level of recursive splitting of the volume"));
|
||||
parlst.addParam (new RichBool("mergeColor",true,"Merge Color","the level of recursive splitting of the volume"));
|
||||
parlst.addParam (new RichBool("mergeColor",true,"Vertex Splatting","This option use a different way to build up the volume, instead of using "));
|
||||
break;
|
||||
default: break; // do not add any parameter for the other filters
|
||||
}
|
||||
}
|
||||
|
||||
// The Real Core Function doing the actual mesh processing.
|
||||
bool PlyMCPlugin::applyFilter(QAction */*filter*/, MeshDocument &md, RichParameterSet & par, vcg::CallBackPos * /*cb*/)
|
||||
bool PlyMCPlugin::applyFilter(QAction */*filter*/, MeshDocument &md, RichParameterSet & par, vcg::CallBackPos * cb)
|
||||
{
|
||||
srand(time(NULL));
|
||||
|
||||
@ -130,9 +130,10 @@ bool PlyMCPlugin::applyFilter(QAction */*filter*/, MeshDocument &md, RichParamet
|
||||
{
|
||||
SMesh sm;
|
||||
mm->updateDataMask(MeshModel::MM_FACEQUALITY);
|
||||
tri::Append<SMesh,CMeshO>::Mesh(sm, mm->cm);
|
||||
tri::Append<SMesh,CMeshO>::Mesh(sm, mm->cm,false,p.VertSplatFlag); // note the last parameter of the append to prevent removal of unreferenced vertices...
|
||||
tri::UpdatePosition<SMesh>::Matrix(sm, mm->cm.Tr,true);
|
||||
tri::UpdateBounding<SMesh>::Box(sm);
|
||||
tri::UpdateNormals<SMesh>::NormalizeVertex(sm);
|
||||
//QString mshTmpPath=QDir::tempPath()+QString("/")+QString(mm->shortName())+QString(".vmi");
|
||||
QString mshTmpPath=QString("__TMP")+QString(mm->shortName())+QString(".vmi");
|
||||
qDebug("Saving tmp file %s",qPrintable(mshTmpPath));
|
||||
@ -146,7 +147,7 @@ bool PlyMCPlugin::applyFilter(QAction */*filter*/, MeshDocument &md, RichParamet
|
||||
}
|
||||
}
|
||||
|
||||
pmc.Process();
|
||||
pmc.Process(cb);
|
||||
|
||||
if(par.getBool("openResult"))
|
||||
{
|
||||
@ -158,9 +159,9 @@ bool PlyMCPlugin::applyFilter(QAction */*filter*/, MeshDocument &md, RichParamet
|
||||
tri::UpdateNormals<CMeshO>::PerVertexPerFace(mp->cm);
|
||||
}
|
||||
}
|
||||
//
|
||||
// for(int i=0;i<pmc.MP.size();++i)
|
||||
// QFile::remove(pmc.MP.MeshName(i).c_str());
|
||||
|
||||
for(int i=0;i<pmc.MP.size();++i)
|
||||
QFile::remove(pmc.MP.MeshName(i).c_str());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -174,60 +174,73 @@ namespace vcg {
|
||||
|
||||
/// PLYMC Methods
|
||||
|
||||
void InitMesh(SMesh &m, const char *filename, Matrix44f Tr)
|
||||
bool InitMesh(SMesh &m, const char *filename, Matrix44f Tr)
|
||||
{
|
||||
tri::io::Importer<SMesh>::Open(m,filename);
|
||||
typename SMesh::VertexIterator vi;
|
||||
int loadmask;
|
||||
int ret = tri::io::Importer<SMesh>::Open(m,filename,loadmask);
|
||||
if(ret)
|
||||
{
|
||||
printf("Error: unabe to open mesh '%s'",filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(p.CleaningFlag){
|
||||
int dup = tri::Clean<SMesh>::RemoveDuplicateVertex(m);
|
||||
int unref = tri::Clean<SMesh>::RemoveUnreferencedVertex(m);
|
||||
printf("Removed %i duplicates and %i unref",dup,unref);
|
||||
if(p.VertSplatFlag)
|
||||
{
|
||||
if(!(loadmask & tri::io::Mask::IOM_VERTNORMAL))
|
||||
{
|
||||
printf("Error, pointset MUST have normals");
|
||||
exit(-1);
|
||||
}
|
||||
else printf("Ok Pointset has normals\n");
|
||||
for(vi=m.vert.begin(); vi!=m.vert.end();++vi)
|
||||
if(math::Abs(SquaredNorm((*vi).N())-1.0)>0.0001)
|
||||
{
|
||||
printf("Error: mesh has not per vertex normalized normals\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!(loadmask & tri::io::Mask::IOM_VERTQUALITY))
|
||||
tri::UpdateQuality<SMesh>::VertexConstant(m,0);
|
||||
tri::UpdateNormals<SMesh>::PerVertexMatrix(m,Tr);
|
||||
//if(!(loadmask & tri::io::Mask::IOM_VERTCOLOR))
|
||||
// saveMask &= ~tri::io::Mask::IOM_VERTCOLOR;
|
||||
}
|
||||
else // processing for triangle meshes
|
||||
{
|
||||
if(p.CleaningFlag){
|
||||
int dup = tri::Clean<SMesh>::RemoveDuplicateVertex(m);
|
||||
int unref = tri::Clean<SMesh>::RemoveUnreferencedVertex(m);
|
||||
printf("Removed %i duplicates and %i unref",dup,unref);
|
||||
}
|
||||
|
||||
tri::UpdateNormals<SMesh>::PerVertexNormalizedPerFaceNormalized(m);
|
||||
if(p.GeodesicQualityFlag) {
|
||||
tri::UpdateTopology<SMesh>::VertexFace(m);
|
||||
tri::UpdateFlags<SMesh>::FaceBorderFromVF(m);
|
||||
tri::UpdateQuality<SMesh>::VertexGeodesicFromBorder(m);
|
||||
}
|
||||
}
|
||||
|
||||
tri::UpdatePosition<SMesh>::Matrix(m,Tr,false);
|
||||
tri::UpdateBounding<SMesh>::Box(m);
|
||||
printf("Init Mesh %s (%ivn,%ifn)\n",filename,m.vn,m.fn);
|
||||
|
||||
|
||||
tri::UpdateNormals<SMesh>::PerVertexNormalizedPerFaceNormalized(m);
|
||||
if(p.GeodesicQualityFlag) {
|
||||
tri::UpdateTopology<SMesh>::VertexFace(m);
|
||||
tri::UpdateFlags<SMesh>::FaceBorderFromVF(m);
|
||||
tri::UpdateQuality<SMesh>::VertexGeodesicFromBorder(m);
|
||||
}
|
||||
|
||||
typename SMesh::VertexIterator vi;
|
||||
|
||||
for(vi=m.vert.begin(); vi!=m.vert.end();++vi)
|
||||
VV.Interize((*vi).P());
|
||||
return true;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// This function add a mesh (or a point cloud to the volume)
|
||||
// the point cloud MUST have normalized vertex normals.
|
||||
|
||||
/// Point cloud inits
|
||||
{
|
||||
if(!(loadmask & tri::io::Mask::IOM_VERTNORMAL))
|
||||
{
|
||||
printf("Error, pointset MUST have normals");
|
||||
exit(-1);
|
||||
}
|
||||
else printf("Ok Pointset has normals\n");
|
||||
|
||||
if(!(loadmask & tri::io::Mask::IOM_VERTQUALITY))
|
||||
tri::UpdateQuality<SMesh>::VertexConstant(m,0);
|
||||
tri::UpdateNormals<SMesh>::PerVertexMatrix(m,Tr);
|
||||
}
|
||||
|
||||
if(!(loadmask & tri::io::Mask::IOM_VERTCOLOR))
|
||||
saveMask &= ~tri::io::Mask::IOM_VERTCOLOR;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Th
|
||||
bool AddMeshToVolumeM(SMesh &m, std::string meshname, const double w )
|
||||
{
|
||||
typename SMesh::VertexIterator vi;
|
||||
typename SMesh::FaceIterator fi;
|
||||
if(!m.bbox.Collide(VV.SubBoxSafe)) return false;
|
||||
size_t found =meshname.find_last_of("/\\");
|
||||
std::string shortname = meshname.substr(found+1);
|
||||
|
||||
Volume <Voxelf> B;
|
||||
B.Init(VV);
|
||||
@ -279,23 +292,23 @@ bool AddMeshToVolumeM(SMesh &m, std::string meshname, const double w )
|
||||
|
||||
int vstp=0;
|
||||
if(p.VerboseLevel>0) {
|
||||
B.SlicedPPM(meshname.c_str(),SFormat("%02i",vstp),p.SliceNum );
|
||||
B.SlicedPPMQ(meshname.c_str(),SFormat("%02i",vstp),p.SliceNum );
|
||||
vstp++;
|
||||
B.SlicedPPM(shortname.c_str(),std::string(SFormat("%02i",vstp)).c_str(),p.SliceNum );
|
||||
B.SlicedPPMQ(shortname.c_str(),std::string(SFormat("%02i",vstp)).c_str(),p.SliceNum );
|
||||
vstp++;
|
||||
}
|
||||
for(int i=0;i<p.WideNum;++i) {
|
||||
B.Expand(math::ToRad(p.ExpAngleDeg));
|
||||
if(p.VerboseLevel>1) B.SlicedPPM(meshname.c_str(),SFormat("%02ie",vstp++),p.SliceNum );
|
||||
if(p.VerboseLevel>1) B.SlicedPPM(shortname.c_str(),SFormat("%02ie",vstp++),p.SliceNum );
|
||||
B.Refill(p.FillThr);
|
||||
if(p.VerboseLevel>1) B.SlicedPPM(meshname.c_str(),SFormat("%02if",vstp++),p.SliceNum );
|
||||
if(p.VerboseLevel>1) B.SlicedPPM(shortname.c_str(),SFormat("%02if",vstp++),p.SliceNum );
|
||||
if(p.IntraSmoothFlag)
|
||||
{
|
||||
Volume <Voxelf> SM;
|
||||
SM.Init(VV);
|
||||
SM.CopySmooth(B,1,p.QualitySmoothAbs);
|
||||
B=SM;
|
||||
if(p.VerboseLevel>1) B.SlicedPPM(meshname.c_str(),SFormat("%02is",vstp++),p.SliceNum );
|
||||
// if(VerboseLevel>1) B.SlicedPPMQ(meshname,SFormat("%02is",vstp),SliceNum );
|
||||
if(p.VerboseLevel>1) B.SlicedPPM(shortname.c_str(),SFormat("%02is",vstp++),p.SliceNum );
|
||||
// if(VerboseLevel>1) B.SlicedPPMQ(shortname,SFormat("%02is",vstp),SliceNum );
|
||||
}
|
||||
}
|
||||
if(p.SmoothNum>0)
|
||||
@ -304,14 +317,14 @@ bool AddMeshToVolumeM(SMesh &m, std::string meshname, const double w )
|
||||
SM.Init(VV);
|
||||
SM.CopySmooth(B,1,p.QualitySmoothAbs);
|
||||
B=SM;
|
||||
if(p.VerboseLevel>1) B.SlicedPPM(meshname.c_str(),SFormat("%02isf",vstp++),p.SliceNum );
|
||||
if(p.VerboseLevel>1) B.SlicedPPM(shortname.c_str(),SFormat("%02isf",vstp++),p.SliceNum );
|
||||
}
|
||||
VV.Merge(B);
|
||||
if(p.VerboseLevel>0) VV.SlicedPPMQ("merge_",meshname.c_str(),p.SliceNum );
|
||||
if(p.VerboseLevel>0) VV.SlicedPPMQ(std::string("merge_").c_str(),shortname.c_str(),p.SliceNum );
|
||||
return true;
|
||||
}
|
||||
|
||||
void Process()
|
||||
void Process(vcg::CallBackPos *cb=0)
|
||||
{
|
||||
printf("bbox scanning...\n"); fflush(stdout);
|
||||
Matrix44f Id; Id.SetIdentity();
|
||||
@ -385,7 +398,12 @@ void Process()
|
||||
SMesh *sm;
|
||||
if(!MP.Find(i,sm) )
|
||||
{
|
||||
InitMesh(*sm,MP.MeshName(i).c_str(),MP.Tr(i));
|
||||
res = InitMesh(*sm,MP.MeshName(i).c_str(),MP.Tr(i));
|
||||
if(!res)
|
||||
{
|
||||
printf("Failed Init of mesh %s",MP.MeshName(i).c_str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
res |= AddMeshToVolumeM(*sm, MP.MeshName(i),MP.W(i));
|
||||
}
|
||||
@ -398,8 +416,8 @@ void Process()
|
||||
VV.Offset(p.OffsetThr);
|
||||
if (p.VerboseLevel>0)
|
||||
{
|
||||
VV.SlicedPPM("finaloff","__",p.SliceNum);
|
||||
VV.SlicedPPMQ("finaloff","__",p.SliceNum);
|
||||
VV.SlicedPPM("finaloff","__",p.SliceNum);
|
||||
VV.SlicedPPMQ("finaloff","__",p.SliceNum);
|
||||
}
|
||||
}
|
||||
//if(p.VerboseLevel>1) VV.SlicedPPM(filename.c_str(),SFormat("_%02im",i),p.SliceNum );
|
||||
|
||||
@ -198,7 +198,7 @@ int main(int argc, char *argv[])
|
||||
// case 'B' : p.SafeBorder =atoi(argv[i]+2);printf("Setting SafeBorder among blocks to %i*%i (default 1)\n",p.SafeBorder,Volume<Voxelf>::BLOCKSIDE());break;
|
||||
case 'p' : p.VertSplatFlag =true; printf("Enabling VertexSplatting instead of face rasterization\n");break;
|
||||
case 'd' : p.VerboseLevel=atoi(argv[i]+2);printf("Enabling VerboseLevel= %i )\n",p.VerboseLevel);break;
|
||||
case 'D' : p.SliceNum=atoi(argv[i]+2);printf("Enabling Debug Volume saving of %i slices (VerboseLevel=1)\n",p.SliceNum);break;
|
||||
case 'D' : p.VerboseLevel=1; p.SliceNum=atoi(argv[i]+2);printf("Enabling Debug Volume saving of %i slices (VerboseLevel=1)\n",p.SliceNum);break;
|
||||
case 'M' : p.SimplificationFlag =true; printf("Enabling PostReconstruction simplification\n"); break;
|
||||
default : {printf("Error unable to parse option '%s'\n",argv[i]); exit(0);}
|
||||
}
|
||||
|
||||
@ -585,7 +585,8 @@ void DeInterize( Point3x & vert ) const // OK
|
||||
bool SplatVert( const Point3x & v0, double quality, const Point3x & nn, Color4b c)
|
||||
{
|
||||
Box3i ibox;
|
||||
|
||||
|
||||
assert(math::Abs(SquaredNorm(nn) - 1.0) < 0.0001); // Just a safety check that the vertex normals are NORMALIZED!
|
||||
ibox.min=Point3i(floor(v0[0]),floor(v0[1]),floor(v0[2]));
|
||||
ibox.max=Point3i( ceil(v0[0]), ceil(v0[1]), ceil(v0[2]));
|
||||
ibox.Intersect(SubPartSafe);
|
||||
@ -1092,7 +1093,7 @@ int Normalize(int thr, float maxdistance=std::numeric_limits<float>::max() )
|
||||
|
||||
|
||||
// Salva
|
||||
void SlicedPPMQ( const char * filename,const char *tag,int SliceNum=1)
|
||||
void SlicedPPMQ( const char * filename,const char *tag,int SliceNum)
|
||||
{
|
||||
std::string basename=filename;
|
||||
std::string name;
|
||||
@ -1167,6 +1168,7 @@ void SlicedPPM( const char * filename,const char *tag,int SliceNum=1)
|
||||
if(iz>=SubPartSafe.min[2] && iz<SubPartSafe.max[2])
|
||||
{
|
||||
name=SFormat("%s_%03i_%s.ppm",filename,iz,tag);
|
||||
printf("Saving slice '%s'",name.c_str());
|
||||
FILE * fp = fopen(name.c_str(),"wb");
|
||||
if(!fp) return;
|
||||
fprintf(fp,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user