Corrected some bug including weighting schema of direction potentially wrong
This commit is contained in:
parent
3b9e18cf4f
commit
c480831b99
|
|
@ -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++)
|
||||||
{
|
{
|
||||||
|
|
@ -87,6 +88,7 @@ class FieldSmoother
|
||||||
if (NMin<-1)NMin=-1;
|
if (NMin<-1)NMin=-1;
|
||||||
|
|
||||||
ScalarType CurvAni=(NMax-NMin)/2;
|
ScalarType CurvAni=(NMax-NMin)/2;
|
||||||
|
CurvAni=std::max(CurvAni,minV);
|
||||||
mesh.vert[i].Q()=CurvAni;
|
mesh.vert[i].Q()=CurvAni;
|
||||||
}
|
}
|
||||||
vcg::tri::UpdateQuality<MeshType>::FaceFromVertex(mesh);
|
vcg::tri::UpdateQuality<MeshType>::FaceFromVertex(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,10 +374,42 @@ 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 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)
|
static void SelectConstraints(MeshType &mesh,SmoothParam &SParam)
|
||||||
{
|
{
|
||||||
//clear all selected faces
|
//clear all selected faces
|
||||||
|
|
@ -399,48 +442,15 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void GloballyOrient(MeshType &mesh)
|
static void SmoothDirectionsIGL(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,
|
|
||||||
int Ndir,
|
int Ndir,
|
||||||
SmoothMethod SMethod=SMNPoly,
|
SmoothMethod SMethod=SMNPoly,
|
||||||
bool HardAsS=true,
|
bool HardAsS=true,
|
||||||
ScalarType alphaSoft=0)
|
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
|
||||||
Eigen::VectorXi SoftI; //soft constraints
|
Eigen::VectorXi SoftI; //soft constraints
|
||||||
|
|
@ -499,11 +509,13 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
static void SmoothDirections(MeshType &mesh,SmoothParam SParam)
|
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
|
// //initialize direction by curvature if needed
|
||||||
if ((SParam.alpha_curv>0)||
|
if ((SParam.alpha_curv>0)||
|
||||||
(SParam.sharp_thr>0)||
|
(SParam.sharp_thr>0)||
|
||||||
|
|
@ -517,10 +529,20 @@ public:
|
||||||
SelectConstraints(mesh,SParam);
|
SelectConstraints(mesh,SParam);
|
||||||
vcg::tri::CrossField<MeshType>::PropagateFromSelF(mesh);
|
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
|
bool weightByAni=(SParam.alpha_curv>0);
|
||||||
SmoothDirections(mesh,SParam.Ndir,SParam.SmoothM,true,SParam.alpha_curv);
|
vcg::tri::CrossField<MeshType>::SmoothIterative(mesh,SParam.Ndir,(int)SParam.IteN,true,false,weightByAni);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue