some minor changes over triangulate and smoothPCA
This commit is contained in:
parent
75243d1cc2
commit
5cc3ca4d70
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue