Update tangent_field_operators.h

added functions InitBorderField , SmoothIterative  and PropagateFromSelF
This commit is contained in:
nico 2019-03-21 16:49:17 +11:00
parent ce75b4e68f
commit ed63e3f7ee
1 changed files with 264 additions and 151 deletions

View File

@ -153,6 +153,8 @@ class CrossField
private:
static void SubDivideDir(const CoordType &Edge0,
const CoordType &Edge1,
std::vector<CoordType> &SubDEdges,
@ -521,6 +523,116 @@ private:
public:
static void InitBorderField(MeshType & mesh)
{
typedef typename MeshType::FaceType FaceType;
typedef typename MeshType::VertexType VertexType;
typedef typename MeshType::CoordType CoordType;
typedef typename MeshType::ScalarType ScalarType;
vcg::tri::UpdateTopology<MeshType>::FaceFace(mesh);
for (size_t i=0;i<mesh.face.size();i++)
for (int j=0;j<mesh.face[i].VN();j++)
{
FaceType *f0=&mesh.face[i];
FaceType *f1=f0->FFp(j);
assert(f1!=NULL);
if (f0!=f1)continue;
CoordType dir=f0->P0(j)-f0->P1(j);
dir.Normalize();
f0->PD1()=dir;
f0->PD2()=f0->N()^dir;
}
}
static void SmoothIterative(MeshType &mesh,int NDir=4,
int NSteps=3,bool FixSelected=false)
{
typedef typename MeshType::FaceType FaceType;
typedef typename MeshType::VertexType VertexType;
typedef typename MeshType::CoordType CoordType;
typedef typename MeshType::ScalarType ScalarType;
vcg::tri::UpdateTopology<MeshType>::FaceFace(mesh);
for (size_t s=0;s<NSteps;s++)
{
std::vector<CoordType> NewPD1(mesh.face.size(),CoordType(0,0,0));
for (size_t i=0;i<mesh.face.size();i++)
{
if ((FixSelected)&&(mesh.face[i].IsS()))continue;
std::vector<CoordType> TangVect;
std::vector<CoordType> Norms;
FaceType *f0=&mesh.face[i];
for (int j=0;j<f0->VN();j++)
{
FaceType *f1=f0->FFp(j);
assert(f1!=NULL);
if (f0==f1)continue;
TangVect.push_back(f1->PD1());
Norms.push_back(f1->N());
}
assert(Norms.size()>0);
std::vector<ScalarType> Weights;
Weights.resize(Norms.size(),1/(ScalarType)Norms.size());
NewPD1[i]=InterpolateCrossField(TangVect,Weights,Norms,f0->N(),NDir);
}
for (size_t i=0;i<mesh.face.size();i++)
{
if ((FixSelected)&&(mesh.face[i].IsS()))continue;
assert(NewPD1[i]!=CoordType(0,0,0));
mesh.face[i].PD1()=NewPD1[i];
mesh.face[i].PD2()=mesh.face[i].N()^mesh.face[i].PD1();
}
}
}
static void PropagateFromSelF(MeshType &mesh)
{
vcg::tri::UpdateTopology<MeshType>::FaceFace(mesh);
//typedef typename std::pair<FaceType*,FaceType*> FacePair;
std::vector<int> queue;
std::vector<int> Sel0;
//initialize the queue
for (int i=0; i<(int)mesh.face.size(); i++)
{
FaceType *f=&(mesh.face[i]);
if (f->IsD())continue;
if (!f->IsS())continue;
queue.push_back(i);
}
Sel0=queue;
assert(queue.size()>0);
do
{
std::vector<int> new_queue;
for (int i=0; i<queue.size(); i++)
{
FaceType *f0=&(mesh.face[queue[i]]);
assert(!f0->IsD());
for (int i=0;i<f0->VN();i++)
{
FaceType *f1=f0->FFp(i);
if (f1==f0)continue;
if (f1->IsS())continue;
f1->PD1()=Rotate(*f0,*f1,f0->PD1());
f1->PD2()=f1->PD1()^f1->N();
f1->SetS();
new_queue.push_back(vcg::tri::Index(mesh,f1));
}
}
queue=new_queue;
}while (queue.size()>0);
//restore selected flag
vcg::tri::UpdateFlags<MeshType>::FaceClearS(mesh);
for (int i=0; i<(int)Sel0.size(); i++)
mesh.face[Sel0[i]].SetS();
}
static size_t FindSeparatrices(const typename vcg::face::Pos<FaceType> &vPos,
std::vector<CoordType> &directions,
std::vector<FaceType*> &faces,
@ -1094,10 +1206,11 @@ public:
static CoordType InterpolateCrossField(const std::vector<CoordType> &TangVect,
const std::vector<ScalarType> &Weight,
const std::vector<CoordType> &Norms,
const CoordType &BaseNorm)
const CoordType &BaseNorm,
int NDir=4)
{
CoordType sum=InterpolateNRosy3D(TangVect,Norms,Weight,4,BaseNorm);
CoordType sum=InterpolateNRosy3D(TangVect,Norms,Weight,NDir,BaseNorm);
return sum;
}