some minor changes over triangulate and smoothPCA

This commit is contained in:
nico 2020-03-22 12:10:34 +11:00
parent 75243d1cc2
commit 5cc3ca4d70
1 changed files with 123 additions and 94 deletions

View File

@ -72,12 +72,12 @@ This class is used to performs varisous kind of geometric optimization on generi
template <class PolyMeshType> template <class PolyMeshType>
class PolygonalAlgorithm class PolygonalAlgorithm
{ {
typedef typename PolyMeshType::FaceType FaceType; typedef typename PolyMeshType::FaceType FaceType;
typedef typename PolyMeshType::VertexType VertexType; typedef typename PolyMeshType::VertexType VertexType;
typedef typename PolyMeshType::VertexPointer VertexPointer; typedef typename PolyMeshType::VertexPointer VertexPointer;
typedef typename PolyMeshType::CoordType CoordType; typedef typename PolyMeshType::CoordType CoordType;
typedef typename PolyMeshType::ScalarType ScalarType; typedef typename PolyMeshType::ScalarType ScalarType;
typedef typename vcg::face::Pos<FaceType> PosType; typedef typename vcg::face::Pos<FaceType> PosType;
public: public:
static bool CollapseEdges(PolyMeshType &poly_m, static bool CollapseEdges(PolyMeshType &poly_m,
const std::vector<PosType> &CollapsePos, const std::vector<PosType> &CollapsePos,
@ -295,7 +295,29 @@ private:
public: public:
static void SelectIrregularInternal(PolyMeshType &poly_m)
{
vcg::tri::UpdateQuality<PolyMeshType>::VertexValence(poly_m);
vcg::tri::UpdateSelection<PolyMeshType>::VertexClear(poly_m);
for (size_t i=0;i<poly_m.vert.size();i++)
{
if (poly_m.vert[i].IsB())continue;
if (poly_m.vert[i].Q()==4)continue;
poly_m.vert[i].SetS();
}
}
static void SelectIrregularBorder(PolyMeshType &poly_m)
{
vcg::tri::UpdateQuality<PolyMeshType>::VertexValence(poly_m);
for (size_t i=0;i<poly_m.vert.size();i++)
{
if (!poly_m.vert[i].IsB())continue;
if (poly_m.vert[i].Q()==2)continue;
poly_m.vert[i].SetS();
}
}
static CoordType GetFaceGetBary(FaceType &F) static CoordType GetFaceGetBary(FaceType &F)
{ {
CoordType bary=PolyBarycenter(F); CoordType bary=PolyBarycenter(F);
@ -413,8 +435,6 @@ public:
ScalarType AvgArea=MeshArea/(ScalarType)poly_m.face.size(); ScalarType AvgArea=MeshArea/(ScalarType)poly_m.face.size();
PolyMeshType TestM;
if (WeightByQuality) if (WeightByQuality)
UpdateQuality(poly_m,QTemplate); UpdateQuality(poly_m,QTemplate);
@ -578,7 +598,8 @@ public:
*/ */
static void LaplacianReprojectBorder(PolyMeshType &poly_m, static void LaplacianReprojectBorder(PolyMeshType &poly_m,
int nstep=100, int nstep=100,
ScalarType Damp=0.5) ScalarType Damp=0.5,
ScalarType Angle=100)
{ {
//transform into triangular //transform into triangular
TempMesh GuideSurf; TempMesh GuideSurf;
@ -588,7 +609,7 @@ public:
vcg::tri::UpdateTopology<TempMesh>::FaceFace(GuideSurf); vcg::tri::UpdateTopology<TempMesh>::FaceFace(GuideSurf);
vcg::tri::UpdateFlags<TempMesh>::FaceBorderFromFF(GuideSurf); vcg::tri::UpdateFlags<TempMesh>::FaceBorderFromFF(GuideSurf);
LaplacianReprojectBorder<TempMesh>(poly_m,GuideSurf,nstep,Damp); LaplacianReprojectBorder<TempMesh>(poly_m,GuideSurf,nstep,Damp,Angle);
} }
/*! \brief This function performs the reprojection of the polygonal mesh onto a triangular one passed as input parameter /*! \brief This function performs the reprojection of the polygonal mesh onto a triangular one passed as input parameter
@ -629,7 +650,7 @@ public:
for (size_t i=0;i<poly_m.vert.size();i++) for (size_t i=0;i<poly_m.vert.size();i++)
{ {
if(OnlyOnSelected && !poly_m.vert[i].IsS()) continue; if(OnlyOnSelected && !poly_m.vert[i].IsS()) continue;
TriCoordType testPos; TriCoordType testPos;
testPos.Import(poly_m.vert[i].P()); testPos.Import(poly_m.vert[i].P());
TriCoordType closestPt; TriCoordType closestPt;
@ -640,7 +661,7 @@ public:
CoordType closestImp; CoordType closestImp;
closestImp.Import(closestPt); closestImp.Import(closestPt);
poly_m.vert[i].P()=poly_m.vert[i].P()*DampR+ poly_m.vert[i].P()=poly_m.vert[i].P()*DampR+
closestImp*(1-DampR); closestImp*(1-DampR);
CoordType normalImp; CoordType normalImp;
normalImp.Import(norm); normalImp.Import(norm);
poly_m.vert[i].N()=normalImp; poly_m.vert[i].N()=normalImp;
@ -692,12 +713,13 @@ public:
static void SmoothReprojectPCA(PolyMeshType &poly_m, static void SmoothReprojectPCA(PolyMeshType &poly_m,
TriMeshType &tri_mesh, TriMeshType &tri_mesh,
int relaxStep=100, int relaxStep=100,
bool fixIrr=false, bool fixS=false,
ScalarType Damp=0.5, ScalarType Damp=0.5,
ScalarType SharpDeg=0, ScalarType SharpDeg=0,
bool WeightByQuality=false) bool WeightByQuality=false,
bool FixB=true)
{ {
vcg::tri::UpdateFlags<PolyMeshType>::VertexClearS(poly_m); //vcg::tri::UpdateFlags<PolyMeshType>::VertexClearS(poly_m);
vcg::tri::UpdateTopology<PolyMeshType>::FaceFace(poly_m); vcg::tri::UpdateTopology<PolyMeshType>::FaceFace(poly_m);
@ -738,16 +760,16 @@ public:
if (SharpEdge[i].size()>2)poly_m.vert[i].SetS(); if (SharpEdge[i].size()>2)poly_m.vert[i].SetS();
} }
} }
if (fixIrr) // if (fixIrr)
{ // {
vcg::tri::UpdateQuality<PolyMeshType>::VertexValence(poly_m); // vcg::tri::UpdateQuality<PolyMeshType>::VertexValence(poly_m);
for (size_t i=0;i<poly_m.vert.size();i++) // for (size_t i=0;i<poly_m.vert.size();i++)
{ // {
if (poly_m.vert[i].IsB())continue; // if (poly_m.vert[i].IsB())continue;
if (poly_m.vert[i].Q()==4)continue; // if (poly_m.vert[i].Q()==4)continue;
poly_m.vert[i].SetS(); // poly_m.vert[i].SetS();
} // }
} // }
typedef typename TriMeshType::FaceType FaceType; typedef typename TriMeshType::FaceType FaceType;
@ -763,22 +785,22 @@ public:
// for (size_t i=0;i<poly_m.face.size();i++) // for (size_t i=0;i<poly_m.face.size();i++)
// poly_m.face[i].Q()=vcg::PolyArea(poly_m.face[i]); // poly_m.face[i].Q()=vcg::PolyArea(poly_m.face[i]);
for (size_t i=0;i<poly_m.vert.size();i++) // for (size_t i=0;i<poly_m.vert.size();i++)
{ // {
typename TriMeshType::CoordType testPos; // typename TriMeshType::CoordType testPos;
testPos.Import(poly_m.vert[i].P()); // testPos.Import(poly_m.vert[i].P());
typename TriMeshType::CoordType closestPt; // typename TriMeshType::CoordType closestPt;
typename TriMeshType::ScalarType minDist; // typename TriMeshType::ScalarType minDist;
typename TriMeshType::FaceType *f=NULL; // typename TriMeshType::FaceType *f=NULL;
typename TriMeshType::CoordType norm,ip; // typename TriMeshType::CoordType norm,ip;
f=vcg::tri::GetClosestFaceBase(tri_mesh,grid,testPos,MaxD,minDist,closestPt,norm,ip); // f=vcg::tri::GetClosestFaceBase(tri_mesh,grid,testPos,MaxD,minDist,closestPt,norm,ip);
//poly_m.vert[i].N().Import(norm); // //poly_m.vert[i].N().Import(norm);
} // }
for(int k=0;k<relaxStep;k++) for(int k=0;k<relaxStep;k++)
{ {
//smooth PCA step //smooth PCA step
SmoothPCA(poly_m,1,Damp,true,true,0.1,true,WeightByQuality); SmoothPCA(poly_m,1,Damp,fixS,true,0.1,FixB,WeightByQuality);
//reprojection step //reprojection step
//laplacian smooth step //laplacian smooth step
//Laplacian(poly_m,Damp,1); //Laplacian(poly_m,Damp,1);
@ -789,32 +811,37 @@ public:
testPos.Import(poly_m.vert[i].P()); testPos.Import(poly_m.vert[i].P());
typename TriMeshType::CoordType closestPt; typename TriMeshType::CoordType closestPt;
typename TriMeshType::ScalarType minDist; typename TriMeshType::ScalarType minDist;
if (SharpEdge[i].size()==0)//reproject onto original mesh if ((FixB)&&(poly_m.vert[i].IsB()))
{ {continue;}
FaceType *f=NULL; else
typename TriMeshType::CoordType norm,ip; if (SharpEdge[i].size()==0)//reproject onto original mesh
f=vcg::tri::GetClosestFaceBase(tri_mesh,grid,testPos,MaxD,minDist,closestPt,norm,ip);
poly_m.vert[i].P().Import(testPos*Damp+closestPt*(1-Damp));
//poly_m.vert[i].N().Import(norm);
}
else //reproject onto segments
{
CoordType av_closest(0,0,0);
size_t sum=0;
for (size_t j=0;j<SharpEdge[i].size();j++)
{ {
CoordType currPos; FaceType *f=NULL;
currPos.Import(testPos); typename TriMeshType::CoordType norm,ip;
CoordType closest; f=vcg::tri::GetClosestFaceBase(tri_mesh,grid,testPos,MaxD,minDist,closestPt,norm,ip);
ScalarType dist; poly_m.vert[i].P().Import(testPos*Damp+closestPt*(1-Damp));
vcg::LinePointDistance(SharpEdge[i][j],currPos,closest,dist); //poly_m.vert[i].N().Import(norm);
av_closest+=closest; }
sum++; else //reproject onto segments
{
CoordType av_closest(0,0,0);
size_t sum=0;
for (size_t j=0;j<SharpEdge[i].size();j++)
{
CoordType currPos;
currPos.Import(testPos);
CoordType closest;
ScalarType dist;
vcg::LinePointDistance(SharpEdge[i][j],currPos,closest,dist);
av_closest+=closest;
sum++;
}
assert(sum>0);
poly_m.vert[i].P()=av_closest/sum;
} }
assert(sum>0);
poly_m.vert[i].P()=av_closest/sum;
}
} }
if (!FixB)
ReprojectBorder(poly_m,tri_mesh,true);
UpdateFaceNormals(poly_m); UpdateFaceNormals(poly_m);
vcg::tri::UpdateNormal<PolyMeshType>::PerVertexFromCurrentFaceNormal(poly_m); vcg::tri::UpdateNormal<PolyMeshType>::PerVertexFromCurrentFaceNormal(poly_m);
} }
@ -840,13 +867,15 @@ public:
*/ */
static void SmoothReprojectPCA(PolyMeshType &poly_m, static void SmoothReprojectPCA(PolyMeshType &poly_m,
int relaxStep=100, int relaxStep=100,
bool fixIrr=false, bool fixS=false,
ScalarType Damp=0.5, ScalarType Damp=0.5,
ScalarType SharpDeg=0, ScalarType SharpDeg=0,
bool WeightByQuality=false) bool WeightByQuality=false,
bool FixB=true)
{ {
//transform into triangular //transform into triangular
TempMesh GuideSurf; TempMesh GuideSurf;
//vcg::tri::PolygonSupport<TempMesh,PolyMeshType>:(GuideSurf,poly_m); //vcg::tri::PolygonSupport<TempMesh,PolyMeshType>:(GuideSurf,poly_m);
TriangulateToTriMesh<TempMesh>(poly_m,GuideSurf); TriangulateToTriMesh<TempMesh>(poly_m,GuideSurf);
vcg::tri::UpdateBounding<TempMesh>::Box(GuideSurf); vcg::tri::UpdateBounding<TempMesh>::Box(GuideSurf);
@ -855,7 +884,7 @@ public:
vcg::tri::UpdateFlags<TempMesh>::FaceBorderFromFF(GuideSurf); vcg::tri::UpdateFlags<TempMesh>::FaceBorderFromFF(GuideSurf);
//optimize it //optimize it
vcg::PolygonalAlgorithm<PolyMeshType>::SmoothReprojectPCA<TempMesh>(poly_m,GuideSurf,relaxStep,fixIrr,Damp,SharpDeg,WeightByQuality); vcg::PolygonalAlgorithm<PolyMeshType>::SmoothReprojectPCA<TempMesh>(poly_m,GuideSurf,relaxStep,fixS,Damp,SharpDeg,WeightByQuality,FixB);
} }
static void Reproject(PolyMeshType &poly_m, static void Reproject(PolyMeshType &poly_m,
@ -1259,42 +1288,42 @@ public:
} }
} }
/*! \brief Triangulate a polygonal face with a triangle fan. /*! \brief Triangulate a polygonal face with a triangle fan.
* \returns pointer to the newly added vertex. * \returns pointer to the newly added vertex.
*/ */
static VertexPointer Triangulate(PolyMeshType & poly_m, size_t IndexF) static VertexPointer Triangulate(PolyMeshType & poly_m, size_t IndexF)
{ {
const CoordType bary = vcg::PolyBarycenter(poly_m.face[IndexF]); const CoordType bary = vcg::PolyBarycenter(poly_m.face[IndexF]);
size_t sizeV = poly_m.face[IndexF].VN(); size_t sizeV = poly_m.face[IndexF].VN();
//add the new vertex //add the new vertex
VertexPointer newV = &(*vcg::tri::Allocator<PolyMeshType>::AddVertex(poly_m,bary)); VertexPointer newV = &(*vcg::tri::Allocator<PolyMeshType>::AddVertex(poly_m,bary));
//then reupdate the faces //then reupdate the faces
for (size_t j=0;j<(sizeV-1);j++) for (size_t j=0;j<(sizeV-1);j++)
{ {
VertexType * v0=poly_m.face[IndexF].V0(j); VertexType * v0=poly_m.face[IndexF].V0(j);
VertexType * v1=poly_m.face[IndexF].V1(j); VertexType * v1=poly_m.face[IndexF].V1(j);
VertexType * v2=newV; VertexType * v2=newV;
vcg::tri::Allocator<PolyMeshType>::AddFaces(poly_m,1); vcg::tri::Allocator<PolyMeshType>::AddFaces(poly_m,1);
poly_m.face.back().Alloc(3); poly_m.face.back().Alloc(3);
poly_m.face.back().V(0)=v0; poly_m.face.back().V(0)=v0;
poly_m.face.back().V(1)=v1; poly_m.face.back().V(1)=v1;
poly_m.face.back().V(2)=v2; poly_m.face.back().V(2)=v2;
} }
VertexType * v0=poly_m.face[IndexF].V0((sizeV-1)); VertexType * v0=poly_m.face[IndexF].V0((sizeV-1));
VertexType * v1=poly_m.face[IndexF].V1((sizeV-1)); VertexType * v1=poly_m.face[IndexF].V1((sizeV-1));
poly_m.face[IndexF].Dealloc(); poly_m.face[IndexF].Dealloc();
poly_m.face[IndexF].Alloc(3); poly_m.face[IndexF].Alloc(3);
poly_m.face[IndexF].V(0)=v0; poly_m.face[IndexF].V(0)=v0;
poly_m.face[IndexF].V(1)=v1; poly_m.face[IndexF].V(1)=v1;
poly_m.face[IndexF].V(2)=newV; poly_m.face[IndexF].V(2)=newV;
return newV; return newV;
} }
static void ReorderFaceVert(FaceType &f,const size_t &StartI) static void ReorderFaceVert(FaceType &f,const size_t &StartI)
{ {