Added new version of pasodoble smoothing
This commit is contained in:
parent
fb23c731ab
commit
d59c8cdc49
|
@ -1,8 +1,13 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include<vcg/simplex/vertex/vertex.h>
|
#include<vcg/simplex/vertexplus/base.h>
|
||||||
#include<vcg/simplex/face/with/fn.h>
|
#include<vcg/simplex/faceplus/base.h>
|
||||||
|
#include<vcg/simplex/face/topology.h>
|
||||||
|
|
||||||
#include<vcg/complex/trimesh/base.h>
|
#include<vcg/complex/trimesh/base.h>
|
||||||
|
|
||||||
|
#include <vcg/complex/trimesh/update/topology.h>
|
||||||
|
#include <vcg/complex/trimesh/update/normal.h>
|
||||||
// to clean up a mesh
|
// to clean up a mesh
|
||||||
#include<vcg/complex/trimesh/clean.h>
|
#include<vcg/complex/trimesh/clean.h>
|
||||||
#include<vcg/complex/trimesh/smooth.h>
|
#include<vcg/complex/trimesh/smooth.h>
|
||||||
|
@ -13,19 +18,29 @@
|
||||||
|
|
||||||
|
|
||||||
using namespace vcg;
|
using namespace vcg;
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
|
||||||
|
class MyEdge; // dummy prototype never used
|
||||||
class MyFace;
|
class MyFace;
|
||||||
class MyEdge;
|
class MyVertex;
|
||||||
class MyVertex:public Vertex<float,MyEdge,MyFace>{};
|
|
||||||
class MyFace :public FaceFN<MyVertex,MyEdge,MyFace>{};
|
|
||||||
class MyMesh: public tri::TriMesh< std::vector<MyVertex>, std::vector<MyFace > >{};
|
|
||||||
|
|
||||||
|
class MyVertex : public VertexSimp2< MyVertex, MyEdge, MyFace, vert::VFAdj, vert::Coord3f, vert::Normal3f, vert::BitFlags >{};
|
||||||
|
class MyFace : public FaceSimp2 < MyVertex, MyEdge, MyFace, face::VFAdj, face::Normal3f, face::VertexRef, face::BitFlags > {};
|
||||||
|
class MyMesh : public vcg::tri::TriMesh<vector<MyVertex>, vector<MyFace> > {};
|
||||||
|
|
||||||
|
//class MyFace;
|
||||||
|
//class MyEdge;
|
||||||
|
//class MyVertex:public Vertex<float,MyEdge,MyFace>{};
|
||||||
|
//class MyFace :public FaceFN<MyVertex,MyEdge,MyFace>{};
|
||||||
|
//class MyMesh: public tri::TriMesh< std::vector<MyVertex>, std::vector<MyFace > >{};
|
||||||
|
//
|
||||||
|
|
||||||
int main(int argc,char ** argv)
|
int main(int argc,char ** argv)
|
||||||
{
|
{
|
||||||
if(argc<3)
|
if(argc<3)
|
||||||
{
|
{
|
||||||
printf("Usage: trimesh_smooth <filename> <steps>\n");
|
printf("Usage: trimesh_smooth <filename> <steps> <sigma> <fitstep>\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,10 +55,18 @@ if(argc<3)
|
||||||
// some cleaning to get rid of bad file formats like stl that duplicate vertexes..
|
// some cleaning to get rid of bad file formats like stl that duplicate vertexes..
|
||||||
int dup = tri::Clean<MyMesh>::RemoveDuplicateVertex(m);
|
int dup = tri::Clean<MyMesh>::RemoveDuplicateVertex(m);
|
||||||
int unref = tri::Clean<MyMesh>::RemoveUnreferencedVertex(m);
|
int unref = tri::Clean<MyMesh>::RemoveUnreferencedVertex(m);
|
||||||
|
|
||||||
printf("Removed %i duplicate and %i unreferenced vertices from mesh %s\n",dup,unref,argv[1]);
|
printf("Removed %i duplicate and %i unreferenced vertices from mesh %s\n",dup,unref,argv[1]);
|
||||||
|
int Step= atoi(argv[2]);
|
||||||
|
tri::UpdateTopology<MyMesh>::VertexFace(m);
|
||||||
|
tri::UpdateNormals<MyMesh>::PerFaceNormalized(m);
|
||||||
|
|
||||||
|
for(int i=0;i<Step;++i)
|
||||||
|
{
|
||||||
|
tri::UpdateNormals<MyMesh>::PerFaceNormalized(m);
|
||||||
|
PasoDobleSmoothFast(m,atoi(argv[3]),atof(argv[4]),atoi(argv[5]));
|
||||||
|
}
|
||||||
|
|
||||||
LaplacianSmooth(m,atoi(argv[2]));
|
//LaplacianSmooth(m,atoi(argv[2]));
|
||||||
tri::io::ExporterPLY<MyMesh>::Save(m,"out.ply");
|
tri::io::ExporterPLY<MyMesh>::Save(m,"out.ply");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -23,6 +23,9 @@
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
History
|
History
|
||||||
$Log: not supported by cvs2svn $
|
$Log: not supported by cvs2svn $
|
||||||
|
Revision 1.9 2006/02/06 10:45:47 cignoni
|
||||||
|
Added missing typenames
|
||||||
|
|
||||||
Revision 1.7 2006/01/24 13:23:22 pietroni
|
Revision 1.7 2006/01/24 13:23:22 pietroni
|
||||||
used template types instead of point3f and float inside function calls
|
used template types instead of point3f and float inside function calls
|
||||||
|
|
||||||
|
@ -534,6 +537,9 @@ void DepthSmooth(MESH_TYPE &m,
|
||||||
/****************************************************************************************************************/
|
/****************************************************************************************************************/
|
||||||
/****************************************************************************************************************/
|
/****************************************************************************************************************/
|
||||||
// Paso Double Smoothing
|
// Paso Double Smoothing
|
||||||
|
// The proposed
|
||||||
|
// approach is a two step method where in the first step the face normals
|
||||||
|
// are adjusted and then, in a second phase, the vertex positions are updated.
|
||||||
/****************************************************************************************************************/
|
/****************************************************************************************************************/
|
||||||
/****************************************************************************************************************/
|
/****************************************************************************************************************/
|
||||||
// Classi di info
|
// Classi di info
|
||||||
|
@ -553,60 +559,55 @@ public:
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
// Paso Doble Step 1 compute the smoothed normals
|
// Paso Doble Step 1 compute the smoothed normals
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
// Calcola la normale media per ogni faccia come area weighted mean con tutte
|
// Requirements:
|
||||||
// le facce adiacenti anche per vertice
|
// VF Topology
|
||||||
//
|
// Normalized Face Normals
|
||||||
|
//
|
||||||
|
// This is the Normal Smoothing approach of Shen and Berner
|
||||||
|
// Fuzzy Vector Median-Based Surface Smoothing TVCG 2004
|
||||||
|
|
||||||
template<class MESH_TYPE>
|
template<class MESH_TYPE>
|
||||||
void NormalSmooth(MESH_TYPE &m,
|
void NormalSmoothSB(MESH_TYPE &m,
|
||||||
SimpleTempData<typename MESH_TYPE::FaceContainer,PDFaceInfo< typename MESH_TYPE::ScalarType > > &TD,
|
SimpleTempData<typename MESH_TYPE::FaceContainer,PDFaceInfo< typename MESH_TYPE::ScalarType > > &TD,
|
||||||
float sigma)
|
typename MESH_TYPE::ScalarType sigma)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
//vcg::face::Pos<typename MESH_TYPE::FaceType> ep;
|
|
||||||
vcg::face::VFIterator<typename MESH_TYPE::FaceType> ep;
|
|
||||||
|
|
||||||
typedef typename MESH_TYPE::CoordType CoordType;
|
typedef typename MESH_TYPE::CoordType CoordType;
|
||||||
typedef typename MESH_TYPE::ScalarType ScalarType;
|
typedef typename MESH_TYPE::ScalarType ScalarType;
|
||||||
typename MESH_TYPE::FaceIterator fi;
|
typename MESH_TYPE::FaceIterator fi;
|
||||||
|
|
||||||
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
||||||
{
|
{
|
||||||
CoordType bc=(*fi).Barycenter();
|
CoordType bc=(*fi).Barycenter();
|
||||||
|
// 1) Clear all the selected flag of faces that are vertex-adjacent to fi
|
||||||
for(i=0;i<3;++i)
|
for(i=0;i<3;++i)
|
||||||
{
|
{
|
||||||
|
vcg::face::VFIterator<typename MESH_TYPE::FaceType> ep(&*fi,i);
|
||||||
ep.f=(*fi).V(i)->VFp();
|
while (!ep.End())
|
||||||
ep.z=(*fi).V(i)->VFi();
|
|
||||||
|
|
||||||
while (!ep.End())
|
|
||||||
{
|
{
|
||||||
ep.f->ClearS();
|
ep.f->ClearS();
|
||||||
++ep;
|
++ep;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 1) Effectively average the normals weighting them with
|
||||||
|
(*fi).SetS();
|
||||||
//TD[*fi]->SetV();
|
|
||||||
(*fi).SetS();
|
|
||||||
CoordType mm=CoordType(0,0,0);
|
CoordType mm=CoordType(0,0,0);
|
||||||
for(i=0;i<3;++i)
|
for(i=0;i<3;++i)
|
||||||
{
|
{
|
||||||
ep.f=(*fi).V(i)->VFp();
|
vcg::face::VFIterator<typename MESH_TYPE::FaceType> ep(&*fi,i);
|
||||||
ep.z=(*fi).V(i)->VFi();
|
while (!ep.End())
|
||||||
while (!ep.End())
|
|
||||||
{
|
{
|
||||||
//if(!TD[*(ep.f)]->IsV())
|
|
||||||
if(! (*ep.f).IsS() )
|
if(! (*ep.f).IsS() )
|
||||||
{
|
{
|
||||||
if(sigma>0)
|
if(sigma>0)
|
||||||
{
|
{
|
||||||
ScalarType dd=SquaredDistance(ep.f->Barycenter(),bc);
|
ScalarType dd=SquaredDistance(ep.f->Barycenter(),bc);
|
||||||
ScalarType ang=Angle(ep.f->N(),(*fi).N());
|
ScalarType ang=AngleN(ep.f->N(),(*fi).N());
|
||||||
mm+=ep.f->N()*exp(((ScalarType)-sigma)*ang*ang/dd);
|
mm+=ep.f->N()*exp((-sigma)*ang*ang/dd);
|
||||||
}
|
}
|
||||||
else mm+=ep.f->N();
|
else mm+=ep.f->N();
|
||||||
//TD[*(ep.f)]->SetV();
|
|
||||||
(*ep.f).SetS();
|
(*ep.f).SetS();
|
||||||
}
|
}
|
||||||
++ep;
|
++ep;
|
||||||
|
@ -614,10 +615,70 @@ void NormalSmooth(MESH_TYPE &m,
|
||||||
}
|
}
|
||||||
mm.Normalize();
|
mm.Normalize();
|
||||||
TD[*fi].m=mm;
|
TD[*fi].m=mm;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
// Paso Doble Step 1 compute the smoothed normals
|
||||||
|
/***************************************************************************/
|
||||||
|
// Requirements:
|
||||||
|
// VF Topology
|
||||||
|
// Normalized Face Normals
|
||||||
|
//
|
||||||
|
// This is the Normal Smoothing approach bsased on a angle thresholded weighting
|
||||||
|
// sigma is in the 0 .. 1 range
|
||||||
|
template<class MESH_TYPE>
|
||||||
|
void NormalSmooth(MESH_TYPE &m,
|
||||||
|
SimpleTempData<typename MESH_TYPE::FaceContainer,PDFaceInfo< typename MESH_TYPE::ScalarType > > &TD,
|
||||||
|
typename MESH_TYPE::ScalarType sigma)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
typedef typename MESH_TYPE::CoordType CoordType;
|
||||||
|
typedef typename MESH_TYPE::ScalarType ScalarType;
|
||||||
|
typedef typename vcg::face::VFIterator<typename MESH_TYPE::FaceType> VFLocalIterator;
|
||||||
|
typename MESH_TYPE::FaceIterator fi;
|
||||||
|
|
||||||
|
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
||||||
|
{
|
||||||
|
CoordType bc=Barycenter<MESH_TYPE::FaceType>(*fi);
|
||||||
|
// 1) Clear all the selected flag of faces that are vertex-adjacent to fi
|
||||||
|
for(i=0;i<3;++i)
|
||||||
|
{
|
||||||
|
VFLocalIterator ep(&*fi,i);
|
||||||
|
for (;!ep.End();++ep)
|
||||||
|
ep.f->ClearS();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1) Effectively average the normals weighting them with
|
||||||
|
//(*fi).SetS();
|
||||||
|
CoordType mm=CoordType(0,0,0);
|
||||||
|
//CoordType mm=(*fi).N();
|
||||||
|
for(i=0;i<3;++i)
|
||||||
|
{
|
||||||
|
VFLocalIterator ep(&*fi,i);
|
||||||
|
for (;!ep.End();++ep)
|
||||||
|
{
|
||||||
|
if(! (*ep.f).IsS() )
|
||||||
|
{
|
||||||
|
ScalarType cosang=ep.f->N()*(*fi).N();
|
||||||
|
if(cosang >= sigma)
|
||||||
|
{
|
||||||
|
ScalarType w = cosang-sigma;
|
||||||
|
mm += ep.f->N()*(w*w);
|
||||||
|
}
|
||||||
|
(*ep.f).SetS();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mm.Normalize();
|
||||||
|
TD[*fi].m=mm;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
||||||
|
(*fi).N()=TD[*fi].m;
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************************************************/
|
/****************************************************************************************************************/
|
||||||
// Restituisce il gradiente dell'area del triangolo nel punto p.
|
// Restituisce il gradiente dell'area del triangolo nel punto p.
|
||||||
// Nota che dovrebbe essere sempre un vettore che giace nel piano del triangolo e perpendicolare al lato opposto al vertice p.
|
// Nota che dovrebbe essere sempre un vettore che giace nel piano del triangolo e perpendicolare al lato opposto al vertice p.
|
||||||
|
@ -708,7 +769,36 @@ void FitMesh(MESH_TYPE &m,
|
||||||
/****************************************************************************************************************/
|
/****************************************************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
template<class MESH_TYPE>
|
||||||
|
void FastFitMesh(MESH_TYPE &m,
|
||||||
|
SimpleTempData<typename MESH_TYPE::VertContainer, PDVertInfo<typename MESH_TYPE::ScalarType> > &TDV,
|
||||||
|
SimpleTempData<typename MESH_TYPE::FaceContainer, PDFaceInfo<typename MESH_TYPE::ScalarType> > &TDF)
|
||||||
|
{
|
||||||
|
//vcg::face::Pos<typename MESH_TYPE::FaceType> ep;
|
||||||
|
vcg::face::VFIterator<typename MESH_TYPE::FaceType> ep;
|
||||||
|
typename MESH_TYPE::VertexIterator vi;
|
||||||
|
typedef typename MESH_TYPE::ScalarType ScalarType;
|
||||||
|
typedef typename MESH_TYPE::CoordType CoordType;
|
||||||
|
typedef typename vcg::face::VFIterator<typename MESH_TYPE::FaceType> VFLocalIterator;
|
||||||
|
|
||||||
|
for(vi=m.vert.begin();vi!=m.vert.end();++vi)
|
||||||
|
{
|
||||||
|
CoordType Sum(0,0,0);
|
||||||
|
ScalarType cnt=0;
|
||||||
|
VFLocalIterator ep(&*vi);
|
||||||
|
for (;!ep.End();++ep)
|
||||||
|
{
|
||||||
|
CoordType bc=Barycenter<MESH_TYPE::FaceType>(*ep.F());
|
||||||
|
Sum += ep.F()->N()*(ep.F()->N()*(bc - (*vi).P()));
|
||||||
|
++cnt;
|
||||||
|
}
|
||||||
|
TDV[*vi].np=(*vi).P()+ Sum*(1.0/cnt);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(vi=m.vert.begin();vi!=m.vert.end();++vi)
|
||||||
|
(*vi).P()=TDV[*vi].np;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -746,6 +836,37 @@ void PasoDobleSmooth(MeshType &m, int step, typename MeshType::ScalarType Sigma=
|
||||||
TDV.Stop();
|
TDV.Stop();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
template<class MeshType>
|
||||||
|
void PasoDobleSmoothFast(MeshType &m, int step, typename MeshType::ScalarType Sigma=0, int FitStep=50)
|
||||||
|
{
|
||||||
|
typedef typename MeshType::ScalarType ScalarType;
|
||||||
|
typedef typename MeshType::CoordType CoordType;
|
||||||
|
|
||||||
|
|
||||||
|
SimpleTempData< typename MeshType::VertContainer, PDVertInfo<ScalarType> > TDV(m.vert);
|
||||||
|
SimpleTempData< typename MeshType::FaceContainer, PDFaceInfo<ScalarType> > TDF(m.face);
|
||||||
|
PDVertInfo<ScalarType> lpzv;
|
||||||
|
lpzv.np=CoordType(0,0,0);
|
||||||
|
PDFaceInfo<ScalarType> lpzf;
|
||||||
|
lpzf.m=CoordType(0,0,0);
|
||||||
|
|
||||||
|
assert(m.HasVFTopology());
|
||||||
|
m.HasVFTopology();
|
||||||
|
TDV.Start(lpzv);
|
||||||
|
TDF.Start(lpzf);
|
||||||
|
|
||||||
|
for(int j=0;j<step;++j)
|
||||||
|
NormalSmooth<MeshType>(m,TDF,Sigma);
|
||||||
|
|
||||||
|
for(int j=0;j<FitStep;++j)
|
||||||
|
FastFitMesh<MeshType>(m,TDV,TDF);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
TDF.Stop();
|
||||||
|
TDV.Stop();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue