Corrected some bug including weighting schema of direction potentially wrong

This commit is contained in:
nico 2021-11-27 07:38:13 +11:00
parent 3b9e18cf4f
commit c480831b99
1 changed files with 95 additions and 73 deletions

View File

@ -46,7 +46,7 @@
namespace vcg { namespace vcg {
namespace tri { namespace tri {
enum SmoothMethod{SMMiq,SMNPoly}; enum SmoothMethod{SMMiq,SMNPoly,SMIterative};
template <class MeshType> template <class MeshType>
class FieldSmoother class FieldSmoother
@ -59,6 +59,7 @@ class FieldSmoother
static void InitQualityByAnisotropyDir(MeshType &mesh) static void InitQualityByAnisotropyDir(MeshType &mesh)
{ {
ScalarType minV=0.00001;
std::vector<ScalarType> QVal; std::vector<ScalarType> QVal;
for (size_t i=0;i<mesh.vert.size();i++) for (size_t i=0;i<mesh.vert.size();i++)
{ {
@ -77,17 +78,18 @@ class FieldSmoother
ScalarType N1=(mesh.vert[i].K1()); ScalarType N1=(mesh.vert[i].K1());
ScalarType N2=(mesh.vert[i].K2()); ScalarType N2=(mesh.vert[i].K2());
ScalarType NMax=std::max(N1,N2)/trimUp; ScalarType NMax=std::max(N1,N2)/trimUp;
ScalarType NMin=std::min(N1,N2)/trimUp; ScalarType NMin=std::min(N1,N2)/trimUp;
if (NMax>1)NMax=1; if (NMax>1)NMax=1;
if (NMax<-1)NMax=-1; if (NMax<-1)NMax=-1;
if (NMin>1)NMin=1; if (NMin>1)NMin=1;
if (NMin<-1)NMin=-1; if (NMin<-1)NMin=-1;
ScalarType CurvAni=(NMax-NMin)/2; ScalarType CurvAni=(NMax-NMin)/2;
mesh.vert[i].Q()=CurvAni; CurvAni=std::max(CurvAni,minV);
mesh.vert[i].Q()=CurvAni;
} }
vcg::tri::UpdateQuality<MeshType>::FaceFromVertex(mesh); vcg::tri::UpdateQuality<MeshType>::FaceFromVertex(mesh);
} }
@ -148,10 +150,10 @@ class FieldSmoother
//hard constraints have selected face //hard constraints have selected face
static void CollectHardConstraints( MeshType & mesh, static void CollectHardConstraints( MeshType & mesh,
Eigen::VectorXi &HardI, Eigen::VectorXi &HardI,
Eigen::MatrixXd &HardD, Eigen::MatrixXd &HardD,
SmoothMethod SMethod, SmoothMethod SMethod,
int Ndir) int Ndir)
{ {
//count number of hard constraints //count number of hard constraints
int numS=vcg::tri::UpdateSelection<MeshType>::FaceCount(mesh); int numS=vcg::tri::UpdateSelection<MeshType>::FaceCount(mesh);
@ -217,7 +219,6 @@ class FieldSmoother
SoftD(curr_index,2)=dir.Z(); SoftD(curr_index,2)=dir.Z();
SoftW(curr_index,0)=mesh.face[i].Q(); SoftW(curr_index,0)=mesh.face[i].Q();
curr_index++; curr_index++;
} }
@ -333,6 +334,14 @@ class FieldSmoother
Dir.Normalize(); Dir.Normalize();
} }
static void GloballyOrient(MeshType &mesh)
{
vcg::tri::CrossField<MeshType>::MakeDirectionFaceCoherent(mesh,true);
}
public: public:
struct SmoothParam struct SmoothParam
@ -353,6 +362,8 @@ public:
int curvRing; int curvRing;
//this are additional hard constraints //this are additional hard constraints
std::vector<std::pair<int,CoordType> > AddConstr; std::vector<std::pair<int,CoordType> > AddConstr;
//the number of iteration in case of iterative method
size_t IteN;
SmoothParam() SmoothParam()
{ {
@ -363,48 +374,11 @@ public:
SmoothM=SMMiq; SmoothM=SMMiq;
sharp_thr=0.0; sharp_thr=0.0;
curv_thr=0.4; curv_thr=0.4;
IteN=20;
} }
}; };
static void SelectConstraints(MeshType &mesh,SmoothParam &SParam)
{
//clear all selected faces
vcg::tri::UpdateFlags<MeshType>::FaceClear(mesh);
//add curvature hard constraints
//ScalarType Ratio=mesh.bbox.Diag()*0.01;
if (SParam.curv_thr>0)
AddCurvatureConstraints(mesh,SParam.curv_thr);///Ratio);
//add alignment to sharp features
if (SParam.sharp_thr>0)
AddSharpEdgesConstraints(mesh,SParam.sharp_thr);
//add border constraints
if (SParam.align_borders)
AddBorderConstraints(mesh);
//aff final constraints
for (size_t i=0;i<SParam.AddConstr.size();i++)
{
int indexF=SParam.AddConstr[i].first;
CoordType dir=SParam.AddConstr[i].second;
mesh.face[indexF].PD1()=dir;
mesh.face[indexF].PD2()=mesh.face[indexF].N()^dir;
mesh.face[indexF].PD1().Normalize();
mesh.face[indexF].PD2().Normalize();
mesh.face[indexF].SetS();
}
}
static void GloballyOrient(MeshType &mesh)
{
vcg::tri::CrossField<MeshType>::MakeDirectionFaceCoherent(mesh,true);
}
static void InitByCurvature(MeshType & mesh, static void InitByCurvature(MeshType & mesh,
unsigned Nring, unsigned Nring,
bool UpdateFaces=true) bool UpdateFaces=true)
@ -434,12 +408,48 @@ public:
InitQualityByAnisotropyDir(mesh); InitQualityByAnisotropyDir(mesh);
} }
static void SmoothDirections(MeshType &mesh, private:
int Ndir,
SmoothMethod SMethod=SMNPoly, static void SelectConstraints(MeshType &mesh,SmoothParam &SParam)
bool HardAsS=true,
ScalarType alphaSoft=0)
{ {
//clear all selected faces
vcg::tri::UpdateFlags<MeshType>::FaceClear(mesh);
//add curvature hard constraints
//ScalarType Ratio=mesh.bbox.Diag()*0.01;
if (SParam.curv_thr>0)
AddCurvatureConstraints(mesh,SParam.curv_thr);///Ratio);
//add alignment to sharp features
if (SParam.sharp_thr>0)
AddSharpEdgesConstraints(mesh,SParam.sharp_thr);
//add border constraints
if (SParam.align_borders)
AddBorderConstraints(mesh);
//aff final constraints
for (size_t i=0;i<SParam.AddConstr.size();i++)
{
int indexF=SParam.AddConstr[i].first;
CoordType dir=SParam.AddConstr[i].second;
mesh.face[indexF].PD1()=dir;
mesh.face[indexF].PD2()=mesh.face[indexF].N()^dir;
mesh.face[indexF].PD1().Normalize();
mesh.face[indexF].PD2().Normalize();
mesh.face[indexF].SetS();
}
}
static void SmoothDirectionsIGL(MeshType &mesh,
int Ndir,
SmoothMethod SMethod=SMNPoly,
bool HardAsS=true,
ScalarType alphaSoft=0)
{
assert((SMethod==SMNPoly)||(SMethod==SMMiq));
Eigen::VectorXi HardI; //hard constraints Eigen::VectorXi HardI; //hard constraints
Eigen::MatrixXd HardD; //hard directions Eigen::MatrixXd HardD; //hard directions
@ -452,7 +462,7 @@ public:
//collect soft constraints , miw only one that allows for soft constraints //collect soft constraints , miw only one that allows for soft constraints
if ((alphaSoft>0)&&(SMethod==SMMiq)) if ((alphaSoft>0)&&(SMethod==SMMiq))
CollectSoftConstraints(mesh,SoftI,SoftD,SoftW); CollectSoftConstraints(mesh,SoftI,SoftD,SoftW);
//add some hard constraints if are not present //add some hard constraints if are not present
int numC=3; int numC=3;
@ -489,9 +499,9 @@ public:
} }
} }
//finally smooth //finally smooth
if (SMethod==SMMiq) if (SMethod==SMMiq)
SmoothMIQ(mesh,HardI,HardD,SoftI,SoftD,SoftW,alphaSoft,Ndir); SmoothMIQ(mesh,HardI,HardD,SoftI,SoftD,SoftW,alphaSoft,Ndir);
else else
{ {
assert(SMethod==SMNPoly); assert(SMethod==SMNPoly);
@ -499,28 +509,40 @@ public:
} }
} }
public:
static void SmoothDirections(MeshType &mesh,SmoothParam SParam) static void SmoothDirections(MeshType &mesh,SmoothParam SParam)
{ {
//for the moment only cross and line field
// //initialize direction by curvature if needed if ((SParam.SmoothM==SMMiq)||(SParam.SmoothM==SMNPoly))
if ((SParam.alpha_curv>0)||
(SParam.sharp_thr>0)||
(SParam.curv_thr>0))
{ {
InitByCurvature(mesh,SParam.curvRing); // //initialize direction by curvature if needed
SelectConstraints(mesh,SParam); if ((SParam.alpha_curv>0)||
(SParam.sharp_thr>0)||
(SParam.curv_thr>0))
{
InitByCurvature(mesh,SParam.curvRing);
SelectConstraints(mesh,SParam);
}
else
{
SelectConstraints(mesh,SParam);
vcg::tri::CrossField<MeshType>::PropagateFromSelF(mesh);
}
SmoothDirectionsIGL(mesh,SParam.Ndir,SParam.SmoothM,true,SParam.alpha_curv);
} }
else else
{ {
SelectConstraints(mesh,SParam); std::cout<<"ITERATIVE"<<std::endl;
vcg::tri::CrossField<MeshType>::PropagateFromSelF(mesh); assert(SParam.SmoothM==SMIterative);
InitByCurvature(mesh,SParam.curvRing);
if ((SParam.sharp_thr>0)||(SParam.curv_thr>0))
SelectConstraints(mesh,SParam);
bool weightByAni=(SParam.alpha_curv>0);
vcg::tri::CrossField<MeshType>::SmoothIterative(mesh,SParam.Ndir,(int)SParam.IteN,true,false,weightByAni);
} }
//then do the actual smooth
SmoothDirections(mesh,SParam.Ndir,SParam.SmoothM,true,SParam.alpha_curv);
} }
}; };