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 tri {
enum SmoothMethod{SMMiq,SMNPoly};
enum SmoothMethod{SMMiq,SMNPoly,SMIterative};
template <class MeshType>
class FieldSmoother
@ -59,6 +59,7 @@ class FieldSmoother
static void InitQualityByAnisotropyDir(MeshType &mesh)
{
ScalarType minV=0.00001;
std::vector<ScalarType> QVal;
for (size_t i=0;i<mesh.vert.size();i++)
{
@ -87,6 +88,7 @@ class FieldSmoother
if (NMin<-1)NMin=-1;
ScalarType CurvAni=(NMax-NMin)/2;
CurvAni=std::max(CurvAni,minV);
mesh.vert[i].Q()=CurvAni;
}
vcg::tri::UpdateQuality<MeshType>::FaceFromVertex(mesh);
@ -217,7 +219,6 @@ class FieldSmoother
SoftD(curr_index,2)=dir.Z();
SoftW(curr_index,0)=mesh.face[i].Q();
curr_index++;
}
@ -333,6 +334,14 @@ class FieldSmoother
Dir.Normalize();
}
static void GloballyOrient(MeshType &mesh)
{
vcg::tri::CrossField<MeshType>::MakeDirectionFaceCoherent(mesh,true);
}
public:
struct SmoothParam
@ -353,6 +362,8 @@ public:
int curvRing;
//this are additional hard constraints
std::vector<std::pair<int,CoordType> > AddConstr;
//the number of iteration in case of iterative method
size_t IteN;
SmoothParam()
{
@ -363,10 +374,42 @@ public:
SmoothM=SMMiq;
sharp_thr=0.0;
curv_thr=0.4;
IteN=20;
}
};
static void InitByCurvature(MeshType & mesh,
unsigned Nring,
bool UpdateFaces=true)
{
tri::RequirePerVertexCurvatureDir(mesh);
Eigen::MatrixXi F;
typename vcg::tri::MeshToMatrix<MeshType>::MatrixXm Vf;
Eigen::MatrixXd PD1,PD2,PV1,PV2;
MeshToMatrix<MeshType>::GetTriMeshData(mesh,F,Vf);
Eigen::MatrixXd V = Vf.template cast<double>();
igl::principal_curvature(V,F,PD1,PD2,PV1,PV2,Nring,true);
//then copy curvature per vertex
for (size_t i=0;i<mesh.vert.size();i++)
{
mesh.vert[i].PD1()=CoordType(PD1(i,0),PD1(i,1),PD1(i,2));
mesh.vert[i].PD2()=CoordType(PD2(i,0),PD2(i,1),PD2(i,2));
mesh.vert[i].K1()=PV1(i,0);
mesh.vert[i].K2()=PV2(i,0);
}
if (!UpdateFaces)return;
vcg::tri::CrossField<MeshType>::SetFaceCrossVectorFromVert(mesh);
InitQualityByAnisotropyDir(mesh);
}
private:
static void SelectConstraints(MeshType &mesh,SmoothParam &SParam)
{
//clear all selected faces
@ -399,48 +442,15 @@ public:
}
}
static void GloballyOrient(MeshType &mesh)
{
vcg::tri::CrossField<MeshType>::MakeDirectionFaceCoherent(mesh,true);
}
static void InitByCurvature(MeshType & mesh,
unsigned Nring,
bool UpdateFaces=true)
{
tri::RequirePerVertexCurvatureDir(mesh);
Eigen::MatrixXi F;
typename vcg::tri::MeshToMatrix<MeshType>::MatrixXm Vf;
Eigen::MatrixXd PD1,PD2,PV1,PV2;
MeshToMatrix<MeshType>::GetTriMeshData(mesh,F,Vf);
Eigen::MatrixXd V = Vf.template cast<double>();
igl::principal_curvature(V,F,PD1,PD2,PV1,PV2,Nring,true);
//then copy curvature per vertex
for (size_t i=0;i<mesh.vert.size();i++)
{
mesh.vert[i].PD1()=CoordType(PD1(i,0),PD1(i,1),PD1(i,2));
mesh.vert[i].PD2()=CoordType(PD2(i,0),PD2(i,1),PD2(i,2));
mesh.vert[i].K1()=PV1(i,0);
mesh.vert[i].K2()=PV2(i,0);
}
if (!UpdateFaces)return;
vcg::tri::CrossField<MeshType>::SetFaceCrossVectorFromVert(mesh);
InitQualityByAnisotropyDir(mesh);
}
static void SmoothDirections(MeshType &mesh,
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::MatrixXd HardD; //hard directions
Eigen::VectorXi SoftI; //soft constraints
@ -499,11 +509,13 @@ public:
}
}
public:
static void SmoothDirections(MeshType &mesh,SmoothParam SParam)
{
//for the moment only cross and line field
if ((SParam.SmoothM==SMMiq)||(SParam.SmoothM==SMNPoly))
{
// //initialize direction by curvature if needed
if ((SParam.alpha_curv>0)||
(SParam.sharp_thr>0)||
@ -517,10 +529,20 @@ public:
SelectConstraints(mesh,SParam);
vcg::tri::CrossField<MeshType>::PropagateFromSelF(mesh);
}
SmoothDirectionsIGL(mesh,SParam.Ndir,SParam.SmoothM,true,SParam.alpha_curv);
}
else
{
std::cout<<"ITERATIVE"<<std::endl;
assert(SParam.SmoothM==SMIterative);
InitByCurvature(mesh,SParam.curvRing);
if ((SParam.sharp_thr>0)||(SParam.curv_thr>0))
SelectConstraints(mesh,SParam);
//then do the actual smooth
SmoothDirections(mesh,SParam.Ndir,SParam.SmoothM,true,SParam.alpha_curv);
bool weightByAni=(SParam.alpha_curv>0);
vcg::tri::CrossField<MeshType>::SmoothIterative(mesh,SParam.Ndir,(int)SParam.IteN,true,false,weightByAni);
}
}
};