reformatted and erased some commented code
This commit is contained in:
parent
c3daffa826
commit
8b0db14e84
|
@ -26,19 +26,20 @@
|
|||
#include <vcg/complex/algorithms/update/flag.h>
|
||||
#include <vcg/simplex/face/topology.h>
|
||||
#include <vcg/complex/algorithms/update/bounding.h>
|
||||
#include <algorithm>
|
||||
|
||||
#ifndef VCG_TANGENT_FIELD_OPERATORS
|
||||
#define VCG_TANGENT_FIELD_OPERATORS
|
||||
|
||||
namespace vcg {
|
||||
namespace tri{
|
||||
namespace tri{
|
||||
|
||||
|
||||
template < typename ScalarType >
|
||||
vcg::Point2<ScalarType> InterpolateNRosy2D(const std::vector<vcg::Point2<ScalarType> > &V,
|
||||
template < typename ScalarType >
|
||||
vcg::Point2<ScalarType> InterpolateNRosy2D(const std::vector<vcg::Point2<ScalarType> > &V,
|
||||
const std::vector<ScalarType> &W,
|
||||
const int N)
|
||||
{
|
||||
{
|
||||
// check parameter
|
||||
assert(V.size() == W.size() && N > 0);
|
||||
|
||||
|
@ -78,22 +79,23 @@ namespace vcg {
|
|||
Res.Y() = std::sin(a);
|
||||
|
||||
return Res;
|
||||
}
|
||||
}
|
||||
|
||||
template < typename ScalarType >
|
||||
vcg::Point3<ScalarType> InterpolateNRosy3D(const std::vector<vcg::Point3<ScalarType> > &V,
|
||||
template < typename ScalarType >
|
||||
vcg::Point3<ScalarType> InterpolateNRosy3D(const std::vector<vcg::Point3<ScalarType> > &V,
|
||||
const std::vector<vcg::Point3<ScalarType> > &Norm,
|
||||
const std::vector<ScalarType> &W,
|
||||
const int N,
|
||||
const vcg::Point3<ScalarType> &TargetN)
|
||||
{
|
||||
{
|
||||
typedef typename vcg::Point3<ScalarType> CoordType;
|
||||
///create a reference frame along TargetN
|
||||
CoordType TargetZ=TargetN;
|
||||
TargetZ.Normalize();
|
||||
CoordType U=CoordType(1,0,0);
|
||||
if (fabs((TargetZ*U)-1.f)<0.001)
|
||||
if (fabs(TargetZ*U)>0.999)
|
||||
U=CoordType(0,1,0);
|
||||
|
||||
CoordType TargetX=TargetZ^U;
|
||||
CoordType TargetY=TargetX^TargetZ;
|
||||
TargetX.Normalize();
|
||||
|
@ -125,20 +127,20 @@ namespace vcg {
|
|||
//transform back to 3D
|
||||
AvDir3D=RotFrameInv*AvDir3D;
|
||||
return AvDir3D;
|
||||
}
|
||||
}
|
||||
|
||||
template <class MeshType>
|
||||
class CrossField
|
||||
{
|
||||
template <class MeshType>
|
||||
class CrossField
|
||||
{
|
||||
typedef typename MeshType::FaceType FaceType;
|
||||
typedef typename MeshType::VertexType VertexType;
|
||||
typedef typename MeshType::CoordType CoordType;
|
||||
typedef typename MeshType::ScalarType ScalarType;
|
||||
|
||||
private:
|
||||
private:
|
||||
static ScalarType Sign(ScalarType a){return (ScalarType)((a>0)?+1:-1);}
|
||||
|
||||
public:
|
||||
public:
|
||||
|
||||
static CoordType FollowDirection(const FaceType &f0,
|
||||
const FaceType &f1,
|
||||
|
@ -196,52 +198,6 @@ namespace vcg {
|
|||
|
||||
}
|
||||
|
||||
static void SetVertCrossFromCurvature(MeshType &mesh)
|
||||
{
|
||||
vcg::tri::UpdateTopology<MeshType>::FaceFace(mesh);
|
||||
vcg::tri::UpdateTopology<MeshType>::VertexFace(mesh);
|
||||
vcg::tri::UpdateBounding<MeshType>::Box(mesh);
|
||||
|
||||
//set as selected high curvature value
|
||||
vcg::tri::UpdateCurvature<MeshType>::PrincipalDirectionsNormalCycles(mesh);
|
||||
NormalizePerVertImportanceVal(mesh);
|
||||
///save the curvature value
|
||||
std::vector<ScalarType> K1,K2;
|
||||
K1.resize(mesh.vert.size());
|
||||
K2.resize(mesh.vert.size());
|
||||
for (int j=0;j<mesh.vert.size();j++)
|
||||
{
|
||||
VertexType *v=&mesh.vert[j];
|
||||
if(v->IsD())continue;
|
||||
K1[j]=v->K1();
|
||||
K2[j]=v->K2();
|
||||
}
|
||||
///then find multiscale curvature directions
|
||||
vcg::tri::UpdateCurvature<MeshType>::PrincipalDirectionsPCA(mesh,mesh.bbox.Diag()/200.0);
|
||||
///and save back importance val
|
||||
for (int j=0;j<mesh.vert.size();j++)
|
||||
{
|
||||
VertexType *v=&mesh.vert[j];
|
||||
if(v->IsD())continue;
|
||||
v->K1()=K1[j];
|
||||
v->K2()=K2[j];
|
||||
}
|
||||
|
||||
///set normal according to curvature
|
||||
for (int j=0;j<mesh.vert.size();j++)
|
||||
{
|
||||
VertexType *v=&mesh.vert[j];
|
||||
if(v->IsD())continue;
|
||||
CoordType N0=v->N();
|
||||
v->N()=v->PD1()^v->PD2();
|
||||
v->N().Normalize();
|
||||
if (N0*v->N()<0)
|
||||
v->N()=-v->N();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
///fird a tranformation matrix to transform
|
||||
///the 3D space to 2D tangent space specified
|
||||
///by the cross field (where Z=0)
|
||||
|
@ -523,25 +479,6 @@ namespace vcg {
|
|||
|
||||
CoordType sum=vcg::tri::InterpolateNRosy3D(V,Norm,W,4,target_n);
|
||||
return sum;
|
||||
// vcg::Matrix33<ScalarType> R0=vcg::RotationMatrix(n0,target_n);
|
||||
// vcg::Matrix33<ScalarType> R1=vcg::RotationMatrix(n1,target_n);
|
||||
// vcg::Matrix33<ScalarType> R2=vcg::RotationMatrix(n2,target_n);
|
||||
// ///rotate
|
||||
// CoordType trans0=R0*t0;
|
||||
// CoordType trans1=R1*t1;
|
||||
// CoordType trans2=R2*t2;
|
||||
// ///normalize it
|
||||
// trans0.Normalize();
|
||||
// trans1.Normalize();
|
||||
// trans2.Normalize();
|
||||
// ///k_PI/2 rotation
|
||||
// trans1=K_PI(trans1,trans0,target_n);
|
||||
// trans2=K_PI(trans2,trans0,target_n);
|
||||
// trans1.Normalize();
|
||||
// trans2.Normalize();
|
||||
|
||||
// CoordType sum = trans0*bary.X() + trans1 * bary.Y() + trans2 * bary.Z();
|
||||
// return sum;
|
||||
}
|
||||
|
||||
///interpolate cross field with barycentric coordinates using normalized weights
|
||||
|
@ -553,19 +490,6 @@ namespace vcg {
|
|||
|
||||
CoordType sum=InterpolateNRosy3D(TangVect,Norms,Weight,4,BaseNorm);
|
||||
return sum;
|
||||
// CoordType sum = CoordType(0,0,0);
|
||||
// for (unsigned int i=0;i<TangVect.size();i++)
|
||||
// {
|
||||
// CoordType N1=Norms[i];
|
||||
// ///find the rotation matrix that maps between normals
|
||||
// vcg::Matrix33<ScalarType> rotation=vcg::RotationMatrix(N1,BaseNorm);
|
||||
// CoordType rotated=rotation*TangVect[i];
|
||||
// CoordType Tdir=K_PI(rotated,BaseDir,BaseNorm);
|
||||
// Tdir.Normalize();
|
||||
// sum+=(Tdir*Weight[i]);
|
||||
// }
|
||||
// sum.Normalize();
|
||||
// return sum;
|
||||
}
|
||||
|
||||
///interpolate cross field with scalar weight
|
||||
|
@ -585,18 +509,6 @@ namespace vcg {
|
|||
W.push_back(weight);
|
||||
W.push_back(1-weight);
|
||||
InterpolateNRosy3D(V,Norm,&W,4,target_n);
|
||||
// vcg::Matrix33<ScalarType> R0=vcg::RotationMatrix(n0,target_n);
|
||||
// vcg::Matrix33<ScalarType> R1=vcg::RotationMatrix(n1,target_n);
|
||||
// CoordType trans0=R0*t0;
|
||||
// CoordType trans1=R1*t1;
|
||||
// //CoordType trans0=t0;//R0*t0;
|
||||
// //CoordType trans1=t1;//R1*t1;
|
||||
// trans0.Normalize();
|
||||
// trans1.Normalize();
|
||||
// trans1=K_PI(trans1,trans0,target_n);
|
||||
// trans1.Normalize();
|
||||
// CoordType sum = trans0*weight + trans1 * (1.0-weight);
|
||||
// return sum;
|
||||
}
|
||||
|
||||
|
||||
|
@ -740,65 +652,94 @@ namespace vcg {
|
|||
dirV = t[1]*UV0.Y() + t[2]*UV1.Y() + t[0]*UV2.Y();
|
||||
}
|
||||
|
||||
|
||||
static void MakeDirectionFaceCoherent(MeshType &mesh)
|
||||
static void MakeDirectionFaceCoherent(FaceType *f0,
|
||||
FaceType *f1)
|
||||
{
|
||||
vcg::tri::UpdateFlags<MeshType>::FaceClearS(mesh);
|
||||
|
||||
std::deque<FaceType*> d;
|
||||
//std::vector<bool> done(mesh.face.size(), false);
|
||||
//for (int i=0; i<(int)mesh.face.size(); i++)
|
||||
// mesh.face[i].ClearS();
|
||||
|
||||
for (int i=0; i<(int)mesh.face.size(); i++)
|
||||
{
|
||||
if (mesh.face[i].IsD())continue;
|
||||
if (mesh.face[i].IsS())continue;
|
||||
mesh.face[i].SetS();
|
||||
d.push_back(&mesh.face[i]);
|
||||
break;
|
||||
}
|
||||
|
||||
while (!d.empty())
|
||||
{
|
||||
while (!d.empty())
|
||||
{
|
||||
FaceType* f0 = d.at(0);
|
||||
d.pop_front();
|
||||
|
||||
for (int k=0; k<3; k++)
|
||||
{
|
||||
FaceType* f1 = f0->FFp(k);
|
||||
if (f1->IsS())continue;
|
||||
if (f1->IsD())continue;
|
||||
if (f1==f0)continue;
|
||||
CoordType dir0=f0->PD1();
|
||||
CoordType dir1=f1->PD1();
|
||||
|
||||
CoordType dir0Rot=Rotate(*f0,*f1,dir0);
|
||||
dir0Rot.Normalize();
|
||||
|
||||
CoordType targD=K_PI(dir1,dir0Rot,f1->N());
|
||||
|
||||
f1->PD1()=targD;
|
||||
f1->PD2()=f1->N()^targD;
|
||||
//f1->PD2()=f1->N()^targD;
|
||||
f1->PD2().Normalize();
|
||||
f1->SetS();
|
||||
d.push_back(f1);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// d is empty: now put first non done element in it
|
||||
static void MakeDirectionFaceCoherent(MeshType &mesh,
|
||||
bool normal_diff=true)
|
||||
{
|
||||
vcg::tri::UpdateFlags<MeshType>::FaceClearV(mesh);
|
||||
vcg::tri::UpdateTopology<MeshType>::FaceFace(mesh);
|
||||
|
||||
typedef typename std::pair<FaceType*,FaceType*> FacePair;
|
||||
std::vector<std::pair<ScalarType,FacePair> > heap;
|
||||
|
||||
while (true)
|
||||
{
|
||||
bool found=false;
|
||||
for (int i=0; i<(int)mesh.face.size(); i++)
|
||||
{
|
||||
if (mesh.face[i].IsD())continue;
|
||||
if (mesh.face[i].IsS())continue;
|
||||
mesh.face[i].SetS();
|
||||
assert(0);
|
||||
d.push_back(&mesh.face[i]);
|
||||
FaceType *f=&(mesh.face[i]);
|
||||
if (f->IsD())continue;
|
||||
if (f->IsV())continue;
|
||||
f->SetV();
|
||||
found=true;
|
||||
|
||||
for (int i=0;i<f->VN();i++)
|
||||
{
|
||||
FaceType *Fopp=f->FFp(i);
|
||||
if (Fopp==f)continue;
|
||||
|
||||
FacePair entry(f,Fopp);
|
||||
|
||||
ScalarType val=0;
|
||||
if (normal_diff)val=-(f->N()-Fopp->N()).Norm();
|
||||
|
||||
heap.push_back(std::pair<ScalarType,FacePair>(val,entry));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
|
||||
vcg::tri::UpdateFlags<MeshType>::FaceClearV(mesh);
|
||||
return;///all faces has been visited
|
||||
}
|
||||
vcg::tri::UpdateFlags<MeshType>::FaceClearS(mesh);
|
||||
|
||||
std::make_heap (heap.begin(),heap.end());
|
||||
|
||||
while (!heap.empty())
|
||||
{
|
||||
std::pop_heap(heap.begin(), heap.end());
|
||||
FaceType *f0=heap.back().second.first;
|
||||
FaceType *f1=heap.back().second.second;
|
||||
assert(f0->IsV());
|
||||
heap.pop_back();
|
||||
|
||||
MakeDirectionFaceCoherent(f0,f1);
|
||||
f1->SetV();
|
||||
for (int k=0; k<f1->VN(); k++)
|
||||
{
|
||||
FaceType* f2 = f1->FFp(k);
|
||||
if (f2->IsV())continue;
|
||||
if (f2->IsD())continue;
|
||||
if (f2==f1)continue;
|
||||
|
||||
FacePair entry(f1,f2);
|
||||
|
||||
ScalarType val=0;
|
||||
if (normal_diff)val=-(f1->N()-f2->N()).Norm();
|
||||
|
||||
heap.push_back(std::pair<ScalarType,FacePair>(val,entry));
|
||||
std::push_heap (heap.begin(),heap.end());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
///transform curvature to UV space
|
||||
|
@ -825,7 +766,7 @@ namespace vcg {
|
|||
return curvUV;
|
||||
}
|
||||
|
||||
};///end class
|
||||
} //End Namespace Tri
|
||||
};///end class
|
||||
} //End Namespace Tri
|
||||
} // End Namespace vcg
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue