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