Merge branch 'devel' of https://github.com/cnr-isti-vclab/vcglib into devel
This commit is contained in:
commit
c0451bb9ed
|
|
@ -535,12 +535,8 @@ void OrientedCone(MeshType & m,
|
||||||
typedef Matrix44<typename MeshType::ScalarType> Matrix44x;
|
typedef Matrix44<typename MeshType::ScalarType> Matrix44x;
|
||||||
Cone(m,r1,r2,Distance(origin,end),SubDiv);
|
Cone(m,r1,r2,Distance(origin,end),SubDiv);
|
||||||
|
|
||||||
// tri::UpdatePosition<MeshType>::Translate(m,CoordType(0,1,0));
|
tri::UpdatePosition<MeshType>::Translate(m,CoordType(0,Distance(origin,end)/2,0));
|
||||||
// tri::UpdatePosition<MeshType>::Scale(m,CoordType(1,0.5f,1));
|
|
||||||
// tri::UpdatePosition<MeshType>::Scale(m,CoordType(xScale,1.0f,yScale));
|
|
||||||
|
|
||||||
// float height = Distance(origin,end);
|
|
||||||
// tri::UpdatePosition<MeshType>::Scale(m,CoordType(radius,height,radius));
|
|
||||||
CoordType norm = end-origin;
|
CoordType norm = end-origin;
|
||||||
ScalarType angleRad = Angle(CoordType(0,1,0),norm);
|
ScalarType angleRad = Angle(CoordType(0,1,0),norm);
|
||||||
const ScalarType Delta= 0.000000001;
|
const ScalarType Delta= 0.000000001;
|
||||||
|
|
@ -560,7 +556,6 @@ void OrientedCone(MeshType & m,
|
||||||
}
|
}
|
||||||
tri::UpdatePosition<MeshType>::Matrix(m,rotM);
|
tri::UpdatePosition<MeshType>::Matrix(m,rotM);
|
||||||
tri::UpdatePosition<MeshType>::Translate(m,origin);
|
tri::UpdatePosition<MeshType>::Translate(m,origin);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -184,13 +184,12 @@ public:
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool MarkFauxEdgeWithPolyLine(MeshType &poly)
|
bool MarkFauxEdgeWithPolyLine(MeshType &poly,bool markFlag=true)
|
||||||
{
|
{
|
||||||
tri::UpdateFlags<MeshType>::FaceSetF(base);
|
if(markFlag) tri::UpdateFlags<MeshType>::FaceSetF(base);
|
||||||
tri::UpdateTopology<MeshType>::VertexFace(base);
|
tri::UpdateTopology<MeshType>::VertexFace(base);
|
||||||
tri::UpdateTopology<MeshType>::FaceFace(base);
|
tri::UpdateTopology<MeshType>::FaceFace(base);
|
||||||
|
|
||||||
bool ret = true;
|
|
||||||
for(EdgeIterator ei=poly.edge.begin(); ei!=poly.edge.end();++ei)
|
for(EdgeIterator ei=poly.edge.begin(); ei!=poly.edge.end();++ei)
|
||||||
{
|
{
|
||||||
CoordType ip0,ip1;
|
CoordType ip0,ip1;
|
||||||
|
|
@ -201,23 +200,30 @@ public:
|
||||||
{
|
{
|
||||||
VertexPointer v0 = FindVertexSnap(f0,ip0);
|
VertexPointer v0 = FindVertexSnap(f0,ip0);
|
||||||
VertexPointer v1 = FindVertexSnap(f1,ip1);
|
VertexPointer v1 = FindVertexSnap(f1,ip1);
|
||||||
assert(v0 != NULL && v1 != NULL && v0 != v1);
|
|
||||||
|
if(v0==0 || v1==0) return false;
|
||||||
|
if(v0==v1) return false;
|
||||||
|
|
||||||
FacePointer ff0,ff1;
|
FacePointer ff0,ff1;
|
||||||
int e0,e1;
|
int e0,e1;
|
||||||
ret &= face::FindSharedFaces<FaceType>(v0,v1,ff0,ff1,e0,e1);
|
bool ret=face::FindSharedFaces<FaceType>(v0,v1,ff0,ff1,e0,e1);
|
||||||
if(ret){
|
if(ret){
|
||||||
|
assert(ret);
|
||||||
assert(ff0->V(e0)==v0 || ff0->V(e0)==v1);
|
assert(ff0->V(e0)==v0 || ff0->V(e0)==v1);
|
||||||
ff0->ClearF(e0);
|
ff0->ClearF(e0);
|
||||||
ff1->ClearF(e1);
|
ff1->ClearF(e1);
|
||||||
}
|
}
|
||||||
}
|
else {
|
||||||
else
|
return false;
|
||||||
{
|
|
||||||
assert(0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
else {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ScalarType MinDistOnEdge(CoordType samplePnt, EdgeGrid &edgeGrid, MeshType &poly, CoordType &closestPoint)
|
ScalarType MinDistOnEdge(CoordType samplePnt, EdgeGrid &edgeGrid, MeshType &poly, CoordType &closestPoint)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,8 @@ class DualMeshing
|
||||||
const PolyMeshType &primal,
|
const PolyMeshType &primal,
|
||||||
std::vector<int> &vertSeq)
|
std::vector<int> &vertSeq)
|
||||||
{
|
{
|
||||||
|
(void)EdgeMap;
|
||||||
|
|
||||||
vcg::face::Pos<FaceType> startP(&startF,&startV);
|
vcg::face::Pos<FaceType> startP(&startF,&startV);
|
||||||
|
|
||||||
//get the star of pos
|
//get the star of pos
|
||||||
|
|
|
||||||
|
|
@ -385,7 +385,7 @@ public:
|
||||||
|
|
||||||
|
|
||||||
///return the number of folded faces
|
///return the number of folded faces
|
||||||
static bool Folded(const FaceType *f)
|
static bool IsFolded(const FaceType *f)
|
||||||
{
|
{
|
||||||
ScalarType areaUV=AreaUV(f);
|
ScalarType areaUV=AreaUV(f);
|
||||||
/*if (areaUV<0)
|
/*if (areaUV<0)
|
||||||
|
|
@ -393,32 +393,30 @@ public:
|
||||||
return (areaUV<0);
|
return (areaUV<0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int Folded(const MeshType &m)
|
static int FoldedNum(const MeshType &m)
|
||||||
{
|
{
|
||||||
int folded=0;
|
int folded=0;
|
||||||
for (size_t i=0;i<m.face.size();i++)
|
|
||||||
{
|
ForEachFace(m, std::function<void (const FaceType&)>([&folded](const FaceType &f){
|
||||||
if (m.face[i].IsD())continue;
|
if(IsFolded(&f)) folded++;
|
||||||
if(Folded(&m.face[i]))folded++;
|
}));
|
||||||
}
|
|
||||||
return folded;
|
return folded;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool GloballyUnFolded(const MeshType &m)
|
static bool GloballyUnFolded(const MeshType &m)
|
||||||
{
|
{
|
||||||
int num=Folded(m);
|
int num=FoldedNum(m);
|
||||||
return (num>(m.fn)/2);
|
return (num>(m.fn)/2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ScalarType MeshAngleDistortion(const MeshType &m)
|
static ScalarType MeshAngleDistortion(const MeshType &m)
|
||||||
{
|
{
|
||||||
ScalarType UDdist=0;
|
ScalarType UDdist=0;
|
||||||
for (size_t i=0;i<m.face.size();i++)
|
ForEachFace(m, std::function<void (const FaceType&)>([&UDdist](const FaceType &f){
|
||||||
{
|
|
||||||
if (m.face[i].IsD())continue;
|
|
||||||
const FaceType *f=&(m.face[i]);
|
|
||||||
UDdist += AngleDistortion(f)*Area3D(f);
|
UDdist += AngleDistortion(f)*Area3D(f);
|
||||||
}
|
}));
|
||||||
|
|
||||||
return UDdist;
|
return UDdist;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@
|
||||||
#ifndef VCG_UV_UTILS
|
#ifndef VCG_UV_UTILS
|
||||||
#define VCG_UV_UTILS
|
#define VCG_UV_UTILS
|
||||||
|
|
||||||
|
|
||||||
namespace vcg {
|
namespace vcg {
|
||||||
namespace tri{
|
namespace tri{
|
||||||
template <class MeshType>
|
template <class MeshType>
|
||||||
|
|
@ -112,6 +111,26 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void GloballyRotate(MeshType &m,ScalarType Angle)
|
||||||
|
{
|
||||||
|
vcg::Box2<ScalarType> BB=PerWedgeUVBox(m);
|
||||||
|
UVCoordType Origin=BB.Center();
|
||||||
|
typename MeshType::FaceIterator fi;
|
||||||
|
for (fi=m.face.begin();fi!=m.face.end();fi++)
|
||||||
|
{
|
||||||
|
if ((*fi).IsD()) continue;
|
||||||
|
for (int i=0;i<3;i++)
|
||||||
|
{
|
||||||
|
(*fi).WT(i).P()-=Origin;
|
||||||
|
ScalarType X1=(*fi).WT(i).P().X()*cos(Angle)-(*fi).WT(i).P().Y()*sin(Angle);
|
||||||
|
ScalarType Y1=(*fi).WT(i).P().X()*cos(Angle)+(*fi).WT(i).P().Y()*sin(Angle);
|
||||||
|
(*fi).WT(i).P().X()=X1;
|
||||||
|
(*fi).WT(i).P().Y()=Y1;
|
||||||
|
(*fi).WT(i).P()+=Origin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void LaplacianUVVert(MeshType &m,bool fix_borders=false,int steps=3)
|
static void LaplacianUVVert(MeshType &m,bool fix_borders=false,int steps=3)
|
||||||
{
|
{
|
||||||
FaceIterator fi;
|
FaceIterator fi;
|
||||||
|
|
|
||||||
|
|
@ -197,7 +197,7 @@ public:
|
||||||
CollectUVBorder(rm,uvBorder);
|
CollectUVBorder(rm,uvBorder);
|
||||||
meshRegionVec.push_back(rm);
|
meshRegionVec.push_back(rm);
|
||||||
uvBorders.push_back(uvBorder);
|
uvBorders.push_back(uvBorder);
|
||||||
int foldedCnt = tri::Distortion<VoroMesh,false>::Folded(*rm);
|
int foldedCnt = tri::Distortion<VoroMesh,false>::FoldedNum(*rm);
|
||||||
if( foldedCnt > rm->fn/10)
|
if( foldedCnt > rm->fn/10)
|
||||||
{
|
{
|
||||||
badRegionVec.push_back(rm);
|
badRegionVec.push_back(rm);
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@
|
||||||
#include <vcg/complex/algorithms/update/color.h>
|
#include <vcg/complex/algorithms/update/color.h>
|
||||||
#include <vcg/complex/algorithms/closest.h>
|
#include <vcg/complex/algorithms/closest.h>
|
||||||
#include <vcg/complex/algorithms/point_sampling.h>
|
#include <vcg/complex/algorithms/point_sampling.h>
|
||||||
|
#include <vcg/complex/algorithms/update/quality.h>
|
||||||
#include <wrap/io_trimesh/export_obj.h>
|
#include <wrap/io_trimesh/export_obj.h>
|
||||||
|
|
||||||
//define a temporary triangle mesh type
|
//define a temporary triangle mesh type
|
||||||
|
|
@ -189,7 +189,7 @@ private:
|
||||||
for (size_t i=0;i<poly_m.face.size();i++)
|
for (size_t i=0;i<poly_m.face.size();i++)
|
||||||
{
|
{
|
||||||
int NumV=poly_m.face[i].VN();
|
int NumV=poly_m.face[i].VN();
|
||||||
for (size_t j=0;j<NumV;j++)
|
for (int j=0;j<NumV;j++)
|
||||||
{
|
{
|
||||||
VertexType *v0=poly_m.face[i].V(j);
|
VertexType *v0=poly_m.face[i].V(j);
|
||||||
VertexType *v1=poly_m.face[i].V((j+1)%NumV);
|
VertexType *v1=poly_m.face[i].V((j+1)%NumV);
|
||||||
|
|
@ -397,7 +397,8 @@ public:
|
||||||
bool FixS=false,
|
bool FixS=false,
|
||||||
bool isotropic=true,
|
bool isotropic=true,
|
||||||
ScalarType smoothTerm=0.1,
|
ScalarType smoothTerm=0.1,
|
||||||
bool fixB=true)
|
bool fixB=true,
|
||||||
|
bool WeightByQuality=false)
|
||||||
{
|
{
|
||||||
(void)isotropic;
|
(void)isotropic;
|
||||||
typedef typename PolyMeshType::FaceType PolygonType;
|
typedef typename PolyMeshType::FaceType PolygonType;
|
||||||
|
|
@ -413,6 +414,9 @@ public:
|
||||||
|
|
||||||
PolyMeshType TestM;
|
PolyMeshType TestM;
|
||||||
|
|
||||||
|
if (WeightByQuality)
|
||||||
|
UpdateQuality(poly_m,QTemplate);
|
||||||
|
|
||||||
for (size_t s=0;s<(size_t)relax_step;s++)
|
for (size_t s=0;s<(size_t)relax_step;s++)
|
||||||
{
|
{
|
||||||
//initialize the accumulation vector
|
//initialize the accumulation vector
|
||||||
|
|
@ -428,7 +432,10 @@ public:
|
||||||
ScalarType val=vcg::PolyArea(poly_m.face[i]);
|
ScalarType val=vcg::PolyArea(poly_m.face[i]);
|
||||||
if (val<(AvgArea*0.00001))
|
if (val<(AvgArea*0.00001))
|
||||||
val=(AvgArea*0.00001);
|
val=(AvgArea*0.00001);
|
||||||
|
|
||||||
ScalarType W=1.0/val;
|
ScalarType W=1.0/val;
|
||||||
|
if (WeightByQuality)
|
||||||
|
W=poly_m.face[i].Q()+0.00001;
|
||||||
|
|
||||||
for (size_t j=0;j<TemplatePos.size();j++)
|
for (size_t j=0;j<TemplatePos.size();j++)
|
||||||
{
|
{
|
||||||
|
|
@ -627,13 +634,63 @@ public:
|
||||||
TriMeshType &tri_mesh,
|
TriMeshType &tri_mesh,
|
||||||
int relaxStep=100,
|
int relaxStep=100,
|
||||||
bool fixIrr=false,
|
bool fixIrr=false,
|
||||||
ScalarType Damp=0.5)
|
ScalarType Damp=0.5,
|
||||||
|
ScalarType SharpDeg=0,
|
||||||
|
bool WeightByQuality=false)
|
||||||
{
|
{
|
||||||
|
vcg::tri::UpdateFlags<PolyMeshType>::VertexClearS(poly_m);
|
||||||
|
|
||||||
vcg::tri::UpdateTopology<PolyMeshType>::FaceFace(poly_m);
|
vcg::tri::UpdateTopology<PolyMeshType>::FaceFace(poly_m);
|
||||||
|
|
||||||
//UpdateBorderVertexFromPFFAdj(poly_m);
|
//UpdateBorderVertexFromPFFAdj(poly_m);
|
||||||
vcg::tri::UpdateFlags<PolyMeshType>::VertexBorderFromFaceAdj(poly_m);
|
vcg::tri::UpdateFlags<PolyMeshType>::VertexBorderFromFaceAdj(poly_m);
|
||||||
|
|
||||||
|
std::vector<std::vector<vcg::Line3<ScalarType> > > SharpEdge(poly_m.vert.size());
|
||||||
|
//first select sharp features
|
||||||
|
if (SharpDeg>0)
|
||||||
|
{
|
||||||
|
for (size_t i=0;i<poly_m.face.size();i++)
|
||||||
|
for (size_t j=0;j<poly_m.face[i].VN();j++)
|
||||||
|
{
|
||||||
|
//check only one side
|
||||||
|
if ((&poly_m.face[i])>=poly_m.face[i].FFp(j))continue;
|
||||||
|
|
||||||
|
CoordType N0=poly_m.face[i].N();
|
||||||
|
CoordType N1=poly_m.face[i].FFp(j)->N();
|
||||||
|
|
||||||
|
ScalarType Angle=vcg::Angle(N0,N1);
|
||||||
|
if (fabs(Angle)>(SharpDeg* (M_PI / 180.0)))
|
||||||
|
{
|
||||||
|
CoordType Pos0=poly_m.face[i].V0(j)->P();
|
||||||
|
CoordType Pos1=poly_m.face[i].V1(j)->P();
|
||||||
|
CoordType Ori=Pos0;
|
||||||
|
CoordType Dir=Pos1-Pos0;
|
||||||
|
Dir.Normalize();
|
||||||
|
vcg::Line3<ScalarType> L(Ori,Dir);
|
||||||
|
int Index0=vcg::tri::Index(poly_m,poly_m.face[i].V0(j));
|
||||||
|
int Index1=vcg::tri::Index(poly_m,poly_m.face[i].V1(j));
|
||||||
|
SharpEdge[Index0].push_back(L);
|
||||||
|
SharpEdge[Index1].push_back(L);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (size_t i=0;i<poly_m.vert.size();i++)
|
||||||
|
{
|
||||||
|
if (SharpEdge[i].size()==0)continue;
|
||||||
|
if (SharpEdge[i].size()>2)poly_m.vert[i].SetS();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fixIrr)
|
||||||
|
{
|
||||||
|
vcg::tri::UpdateQuality<PolyMeshType>::VertexValence(poly_m);
|
||||||
|
for (size_t i=0;i<poly_m.vert.size();i++)
|
||||||
|
{
|
||||||
|
if (poly_m.vert[i].IsB())continue;
|
||||||
|
if (poly_m.vert[i].Q()==4)continue;
|
||||||
|
poly_m.vert[i].SetS();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
typedef typename TriMeshType::FaceType FaceType;
|
typedef typename TriMeshType::FaceType FaceType;
|
||||||
typedef vcg::GridStaticPtr<FaceType, typename TriMeshType::ScalarType> TriMeshGrid;
|
typedef vcg::GridStaticPtr<FaceType, typename TriMeshType::ScalarType> TriMeshGrid;
|
||||||
TriMeshGrid grid;
|
TriMeshGrid grid;
|
||||||
|
|
@ -656,13 +713,13 @@ public:
|
||||||
typename TriMeshType::FaceType *f=NULL;
|
typename TriMeshType::FaceType *f=NULL;
|
||||||
typename TriMeshType::CoordType norm,ip;
|
typename TriMeshType::CoordType norm,ip;
|
||||||
f=vcg::tri::GetClosestFaceBase(tri_mesh,grid,testPos,MaxD,minDist,closestPt,norm,ip);
|
f=vcg::tri::GetClosestFaceBase(tri_mesh,grid,testPos,MaxD,minDist,closestPt,norm,ip);
|
||||||
poly_m.vert[i].N().Import(norm);
|
//poly_m.vert[i].N().Import(norm);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int k=0;k<relaxStep;k++)
|
for(int k=0;k<relaxStep;k++)
|
||||||
{
|
{
|
||||||
//smooth PCA step
|
//smooth PCA step
|
||||||
SmoothPCA(poly_m,1,Damp,fixIrr);
|
SmoothPCA(poly_m,1,Damp,true,true,0.1,true,WeightByQuality);
|
||||||
//reprojection step
|
//reprojection step
|
||||||
//laplacian smooth step
|
//laplacian smooth step
|
||||||
//Laplacian(poly_m,Damp,1);
|
//Laplacian(poly_m,Damp,1);
|
||||||
|
|
@ -673,13 +730,48 @@ public:
|
||||||
testPos.Import(poly_m.vert[i].P());
|
testPos.Import(poly_m.vert[i].P());
|
||||||
typename TriMeshType::CoordType closestPt;
|
typename TriMeshType::CoordType closestPt;
|
||||||
typename TriMeshType::ScalarType minDist;
|
typename TriMeshType::ScalarType minDist;
|
||||||
|
if (SharpEdge[i].size()==0)//reproject onto original mesh
|
||||||
|
{
|
||||||
FaceType *f=NULL;
|
FaceType *f=NULL;
|
||||||
typename TriMeshType::CoordType norm,ip;
|
typename TriMeshType::CoordType norm,ip;
|
||||||
f=vcg::tri::GetClosestFaceBase(tri_mesh,grid,testPos,MaxD,minDist,closestPt,norm,ip);
|
f=vcg::tri::GetClosestFaceBase(tri_mesh,grid,testPos,MaxD,minDist,closestPt,norm,ip);
|
||||||
poly_m.vert[i].P().Import(testPos*Damp+closestPt*(1-Damp));
|
poly_m.vert[i].P().Import(testPos*Damp+closestPt*(1-Damp));
|
||||||
poly_m.vert[i].N().Import(norm);
|
//poly_m.vert[i].N().Import(norm);
|
||||||
|
}
|
||||||
|
else //reproject onto segments
|
||||||
|
{
|
||||||
|
CoordType av_closest(0,0,0);
|
||||||
|
size_t sum=0;
|
||||||
|
for (size_t j=0;j<SharpEdge[i].size();j++)
|
||||||
|
{
|
||||||
|
CoordType closest;
|
||||||
|
ScalarType dist;
|
||||||
|
vcg::LinePointDistance(SharpEdge[i][j],testPos,closest,dist);
|
||||||
|
av_closest+=closest;
|
||||||
|
sum++;
|
||||||
|
}
|
||||||
|
assert(sum>0);
|
||||||
|
poly_m.vert[i].P()=av_closest/sum;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
UpdateFaceNormals(poly_m);
|
||||||
|
vcg::tri::UpdateNormal<PolyMeshType>::PerVertexFromCurrentFaceNormal(poly_m);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class TriMeshType>
|
||||||
|
static void TriangulateToTriMesh(PolyMeshType &poly_m,TriMeshType &triangle_mesh)
|
||||||
|
{
|
||||||
|
triangle_mesh.Clear();
|
||||||
|
|
||||||
|
PolyMeshType PolySwap;
|
||||||
|
vcg::tri::Append<PolyMeshType,PolyMeshType>::Mesh(PolySwap,poly_m);
|
||||||
|
Triangulate(PolySwap);
|
||||||
|
|
||||||
|
//then copy onto the triangle mesh
|
||||||
|
vcg::tri::Append<TriMeshType,PolyMeshType>::Mesh(triangle_mesh,PolySwap);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \brief This function performs the polygon regularization as in "Statics Aware Grid Shells"
|
/*! \brief This function performs the polygon regularization as in "Statics Aware Grid Shells"
|
||||||
|
|
@ -688,18 +780,21 @@ public:
|
||||||
static void SmoothReprojectPCA(PolyMeshType &poly_m,
|
static void SmoothReprojectPCA(PolyMeshType &poly_m,
|
||||||
int relaxStep=100,
|
int relaxStep=100,
|
||||||
bool fixIrr=false,
|
bool fixIrr=false,
|
||||||
ScalarType Damp=0.5)
|
ScalarType Damp=0.5,
|
||||||
|
ScalarType SharpDeg=0,
|
||||||
|
bool WeightByQuality=false)
|
||||||
{
|
{
|
||||||
//transform into triangular
|
//transform into triangular
|
||||||
TempMesh GuideSurf;
|
TempMesh GuideSurf;
|
||||||
vcg::tri::PolygonSupport<TempMesh,PolyMeshType>::ImportFromPolyMesh(GuideSurf,poly_m);
|
//vcg::tri::PolygonSupport<TempMesh,PolyMeshType>:(GuideSurf,poly_m);
|
||||||
|
TriangulateToTriMesh<TempMesh>(poly_m,GuideSurf);
|
||||||
vcg::tri::UpdateBounding<TempMesh>::Box(GuideSurf);
|
vcg::tri::UpdateBounding<TempMesh>::Box(GuideSurf);
|
||||||
vcg::tri::UpdateNormal<TempMesh>::PerVertexNormalizedPerFace(GuideSurf);
|
vcg::tri::UpdateNormal<TempMesh>::PerVertexNormalizedPerFace(GuideSurf);
|
||||||
vcg::tri::UpdateTopology<TempMesh>::FaceFace(GuideSurf);
|
vcg::tri::UpdateTopology<TempMesh>::FaceFace(GuideSurf);
|
||||||
vcg::tri::UpdateFlags<TempMesh>::FaceBorderFromFF(GuideSurf);
|
vcg::tri::UpdateFlags<TempMesh>::FaceBorderFromFF(GuideSurf);
|
||||||
|
|
||||||
//optimize it
|
//optimize it
|
||||||
vcg::PolygonalAlgorithm<PolyMeshType>::SmoothReprojectPCA<TempMesh>(poly_m,GuideSurf,relaxStep,fixIrr,Damp);
|
vcg::PolygonalAlgorithm<PolyMeshType>::SmoothReprojectPCA<TempMesh>(poly_m,GuideSurf,relaxStep,fixIrr,Damp,SharpDeg,WeightByQuality);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \brief This function return average edge size
|
/*! \brief This function return average edge size
|
||||||
|
|
@ -711,7 +806,7 @@ public:
|
||||||
for (size_t i=0;i<poly_m.face.size();i++)
|
for (size_t i=0;i<poly_m.face.size();i++)
|
||||||
{
|
{
|
||||||
int NumV=poly_m.face[i].VN();
|
int NumV=poly_m.face[i].VN();
|
||||||
for (size_t j=0;j<NumV;j++)
|
for (int j=0;j<NumV;j++)
|
||||||
{
|
{
|
||||||
CoordType pos0=poly_m.face[i].cV(j)->P();
|
CoordType pos0=poly_m.face[i].cV(j)->P();
|
||||||
CoordType pos1=poly_m.face[i].cV((j+1)%NumV)->P();
|
CoordType pos1=poly_m.face[i].cV((j+1)%NumV)->P();
|
||||||
|
|
@ -763,7 +858,7 @@ public:
|
||||||
//get vertices of the face
|
//get vertices of the face
|
||||||
int NumV=poly_m.face[i].VN();
|
int NumV=poly_m.face[i].VN();
|
||||||
|
|
||||||
for (size_t j=0;j<NumV;j++)
|
for (int j=0;j<NumV;j++)
|
||||||
{
|
{
|
||||||
VertexType *v0=poly_m.face[i].V((j+NumV-1)%NumV);
|
VertexType *v0=poly_m.face[i].V((j+NumV-1)%NumV);
|
||||||
VertexType *v1=poly_m.face[i].V(j);
|
VertexType *v1=poly_m.face[i].V(j);
|
||||||
|
|
@ -801,7 +896,7 @@ public:
|
||||||
int NumV=poly_m.face[i].VN();
|
int NumV=poly_m.face[i].VN();
|
||||||
|
|
||||||
std::vector<VertexType*> FaceV;
|
std::vector<VertexType*> FaceV;
|
||||||
for (size_t j=0;j<NumV;j++)
|
for (int j=0;j<NumV;j++)
|
||||||
{
|
{
|
||||||
VertexType *v=poly_m.face[i].V(j);
|
VertexType *v=poly_m.face[i].V(j);
|
||||||
assert(!v->IsD());
|
assert(!v->IsD());
|
||||||
|
|
@ -813,7 +908,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
//then deallocate face
|
//then deallocate face
|
||||||
if (FaceV.size()==NumV)continue;
|
if ((int)FaceV.size()==NumV)continue;
|
||||||
|
|
||||||
//otherwise deallocate and set new vertices
|
//otherwise deallocate and set new vertices
|
||||||
poly_m.face[i].Dealloc();
|
poly_m.face[i].Dealloc();
|
||||||
|
|
@ -925,7 +1020,7 @@ public:
|
||||||
// ScalarType AreaF=vcg::PolyArea(poly_m.face[i]);
|
// ScalarType AreaF=vcg::PolyArea(poly_m.face[i]);
|
||||||
size_t sizeV=poly_m.face[i].VN()-1;
|
size_t sizeV=poly_m.face[i].VN()-1;
|
||||||
CoordType baryF=vcg::PolyBarycenter(poly_m.face[i]);
|
CoordType baryF=vcg::PolyBarycenter(poly_m.face[i]);
|
||||||
for (size_t j=0;j<poly_m.face[i].VN();j++)
|
for (int j=0;j<poly_m.face[i].VN();j++)
|
||||||
{
|
{
|
||||||
CoordType P0=poly_m.face[i].P((j+sizeV-1)%sizeV);
|
CoordType P0=poly_m.face[i].P((j+sizeV-1)%sizeV);
|
||||||
CoordType P1=poly_m.face[i].P(j);
|
CoordType P1=poly_m.face[i].P(j);
|
||||||
|
|
@ -939,6 +1034,25 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void InitQualityVertEdgeLenght(PolyMeshType &poly_m)
|
||||||
|
{
|
||||||
|
for (size_t i=0;i<poly_m.vert.size();i++)
|
||||||
|
poly_m.vert[i].Q()=0;
|
||||||
|
|
||||||
|
for (size_t i=0;i<poly_m.face.size();i++)
|
||||||
|
{
|
||||||
|
for (int j=0;j<poly_m.face[i].VN();j++)
|
||||||
|
{
|
||||||
|
FaceType *f=&poly_m.face[i];
|
||||||
|
FaceType *f1=f->FFp(j);
|
||||||
|
if (f>f1)continue;
|
||||||
|
ScalarType L=(poly_m.face[i].P0(j)-poly_m.face[i].P1(j)).Norm();
|
||||||
|
poly_m.face[i].V0(j)->Q()+=L;
|
||||||
|
poly_m.face[i].V1(j)->Q()+=L;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void InterpolateQualityVertFormFaces(PolyMeshType &poly_m)
|
static void InterpolateQualityVertFormFaces(PolyMeshType &poly_m)
|
||||||
{
|
{
|
||||||
std::vector<ScalarType> SumW(poly_m.vert.size(),0);
|
std::vector<ScalarType> SumW(poly_m.vert.size(),0);
|
||||||
|
|
@ -1027,18 +1141,6 @@ public:
|
||||||
Triangulate(poly_m,i);
|
Triangulate(poly_m,i);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class TriMeshType>
|
|
||||||
static void TriangulateToTriMesh(PolyMeshType &poly_m,TriMeshType &triangle_mesh)
|
|
||||||
{
|
|
||||||
triangle_mesh.Clear();
|
|
||||||
|
|
||||||
PolyMeshType PolySwap;
|
|
||||||
vcg::tri::Append<PolyMeshType,PolyMeshType>::Mesh(PolySwap,poly_m);
|
|
||||||
Triangulate(PolySwap);
|
|
||||||
|
|
||||||
//then copy onto the triangle mesh
|
|
||||||
vcg::tri::Append<TriMeshType,PolyMeshType>::Mesh(triangle_mesh,PolySwap);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}//end namespace vcg
|
}//end namespace vcg
|
||||||
|
|
|
||||||
|
|
@ -135,7 +135,7 @@ private:
|
||||||
{
|
{
|
||||||
ScalarType minTolerance=precisionQ;
|
ScalarType minTolerance=precisionQ;
|
||||||
//first add all eddge
|
//first add all eddge
|
||||||
for (int i=0;i<to_split.face.size();i++)
|
for (size_t i=0;i<to_split.face.size();i++)
|
||||||
{
|
{
|
||||||
TriFaceType *f=&to_split.face[i];
|
TriFaceType *f=&to_split.face[i];
|
||||||
for (int j =0;j<3;j++)
|
for (int j =0;j<3;j++)
|
||||||
|
|
@ -158,7 +158,7 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RoundSplits(TriMesh &to_split,int dir)
|
void RoundSplits(TriMesh &to_split)//,int dir)
|
||||||
{
|
{
|
||||||
ScalarType minTolerance=precisionQ;
|
ScalarType minTolerance=precisionQ;
|
||||||
//first add all eddge
|
//first add all eddge
|
||||||
|
|
@ -191,14 +191,13 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitSplitMap(TriMesh &to_split,
|
void InitSplitMap(TriMesh &to_split,int dir)
|
||||||
int dir)
|
|
||||||
{
|
{
|
||||||
assert((dir==0)||(dir==1));
|
//assert((dir==0)||(dir==1));
|
||||||
InterpMap.clear();
|
InterpMap.clear();
|
||||||
//printf("direction %d\n",dir );
|
//printf("direction %d\n",dir );
|
||||||
//first add all eddge
|
//first add all eddge
|
||||||
for (int i=0;i<to_split.face.size();i++)
|
for (size_t i=0;i<to_split.face.size();i++)
|
||||||
{
|
{
|
||||||
TriFaceType *f=&to_split.face[i];
|
TriFaceType *f=&to_split.face[i];
|
||||||
for (int j =0;j<3;j++)
|
for (int j =0;j<3;j++)
|
||||||
|
|
@ -311,7 +310,7 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RoundSplits(to_split,dir);
|
RoundSplits(to_split);//,dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Basic subdivision class
|
// Basic subdivision class
|
||||||
|
|
@ -353,6 +352,8 @@ private:
|
||||||
vcg::TexCoord2<ScalarType> WedgeInterp(vcg::TexCoord2<ScalarType> &t0,
|
vcg::TexCoord2<ScalarType> WedgeInterp(vcg::TexCoord2<ScalarType> &t0,
|
||||||
vcg::TexCoord2<ScalarType> &t1)
|
vcg::TexCoord2<ScalarType> &t1)
|
||||||
{
|
{
|
||||||
|
(void)t0;
|
||||||
|
(void)t1;
|
||||||
return (vcg::TexCoord2<ScalarType>(0,0));
|
return (vcg::TexCoord2<ScalarType>(0,0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -440,7 +441,7 @@ private:
|
||||||
for (int dir=0;dir<2;dir++)
|
for (int dir=0;dir<2;dir++)
|
||||||
{
|
{
|
||||||
ScalarType val0=uv.V(dir);
|
ScalarType val0=uv.V(dir);
|
||||||
int integer0=floor(val0+0.5);
|
//int integer0=floor(val0+0.5);
|
||||||
//if ((fabs(val0-(ScalarType)integer0))<UVtolerance)onIntegerL++;
|
//if ((fabs(val0-(ScalarType)integer0))<UVtolerance)onIntegerL++;
|
||||||
if (val0==(ScalarType)floor(val0))onIntegerL++;
|
if (val0==(ScalarType)floor(val0))onIntegerL++;
|
||||||
}
|
}
|
||||||
|
|
@ -510,7 +511,7 @@ private:
|
||||||
poly.push_back(currPos.V());
|
poly.push_back(currPos.V());
|
||||||
|
|
||||||
//retrieve UV
|
//retrieve UV
|
||||||
int indexV0=currPos.E();
|
//int indexV0=currPos.E();
|
||||||
|
|
||||||
short int Align=AlignmentEdge(currPos.F(),currPos.E());
|
short int Align=AlignmentEdge(currPos.F(),currPos.E());
|
||||||
|
|
||||||
|
|
@ -606,7 +607,7 @@ private:
|
||||||
|
|
||||||
void ConvertWTtoVT(TriMesh &Tmesh)
|
void ConvertWTtoVT(TriMesh &Tmesh)
|
||||||
{
|
{
|
||||||
int vn = Tmesh.vn;
|
//int vn = Tmesh.vn;
|
||||||
vcg::tri::AttributeSeam::SplitVertex(Tmesh, ExtractVertex, CompareVertex);
|
vcg::tri::AttributeSeam::SplitVertex(Tmesh, ExtractVertex, CompareVertex);
|
||||||
vcg::tri::UpdateTopology<TriMesh>::FaceFace(Tmesh);
|
vcg::tri::UpdateTopology<TriMesh>::FaceFace(Tmesh);
|
||||||
// vcg::tri::UpdateFlags<TriMesh>::FaceBorderFromFF(Tmesh);
|
// vcg::tri::UpdateFlags<TriMesh>::FaceBorderFromFF(Tmesh);
|
||||||
|
|
@ -712,7 +713,7 @@ public:
|
||||||
|
|
||||||
InitIntegerEdgesVert(Tmesh);
|
InitIntegerEdgesVert(Tmesh);
|
||||||
|
|
||||||
for (int i=0;i<Tmesh.face.size();i++)
|
for (size_t i=0;i<Tmesh.face.size();i++)
|
||||||
Tmesh.face[i].C()=vcg::Color4b(255,255,255,255);
|
Tmesh.face[i].C()=vcg::Color4b(255,255,255,255);
|
||||||
|
|
||||||
if (preserve_border_corner)
|
if (preserve_border_corner)
|
||||||
|
|
|
||||||
|
|
@ -447,7 +447,7 @@ static void PerVertexAddNoise(MeshType& m, int noiseBits, bool onSelected=false)
|
||||||
|
|
||||||
/*! \brief Reduces vertex color the mesh to two colors according to a threshold.
|
/*! \brief Reduces vertex color the mesh to two colors according to a threshold.
|
||||||
*/
|
*/
|
||||||
static int PerVertexThresholding(MeshType &m, float threshold, Color4b c1 = Color4<unsigned char>::Black, Color4b c2 = Color4<unsigned char>::White, const bool ProcessSelected=false)
|
static int PerVertexThresholding(MeshType &m, float threshold, const Color4b c1 = Color4<unsigned char>::Black, const Color4b c2 = Color4<unsigned char>::White, const bool ProcessSelected=false)
|
||||||
{
|
{
|
||||||
RequirePerVertexColor(m);
|
RequirePerVertexColor(m);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -347,6 +347,17 @@ public:
|
||||||
return ei;
|
return ei;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Function to add a single edge to the mesh. and initializing it with two indexes to the vertexes
|
||||||
|
*/
|
||||||
|
static EdgeIterator AddEdge(MeshType &m, size_t v0, size_t v1)
|
||||||
|
{
|
||||||
|
assert(v0!=v1);
|
||||||
|
assert(v0>=0 && v0<m.vert.size());
|
||||||
|
assert(v1>=0 && v1<m.vert.size());
|
||||||
|
return AddEdge(m,&(m.vert[v0]),&(m.vert[v1]));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Function to add a face to the mesh and initializing it with the three given coords
|
/** Function to add a face to the mesh and initializing it with the three given coords
|
||||||
*/
|
*/
|
||||||
static EdgeIterator AddEdge(MeshType &m, CoordType p0, CoordType p1)
|
static EdgeIterator AddEdge(MeshType &m, CoordType p0, CoordType p1)
|
||||||
|
|
@ -501,9 +512,9 @@ public:
|
||||||
static FaceIterator AddFace(MeshType &m, size_t v0, size_t v1, size_t v2)
|
static FaceIterator AddFace(MeshType &m, size_t v0, size_t v1, size_t v2)
|
||||||
{
|
{
|
||||||
assert((v0!=v1) && (v1!=v2) && (v0!=v2));
|
assert((v0!=v1) && (v1!=v2) && (v0!=v2));
|
||||||
assert(v0>=0 && v0<=m.vert.size());
|
assert(v0>=0 && v0<m.vert.size());
|
||||||
assert(v1>=0 && v1<=m.vert.size());
|
assert(v1>=0 && v1<m.vert.size());
|
||||||
assert(v2>=0 && v2<=m.vert.size());
|
assert(v2>=0 && v2<m.vert.size());
|
||||||
return AddFace(m,&(m.vert[v0]),&(m.vert[v1]),&(m.vert[v2]));
|
return AddFace(m,&(m.vert[v0]),&(m.vert[v1]),&(m.vert[v2]));
|
||||||
}
|
}
|
||||||
/** Function to add a face to the mesh and initializing it with the three given coords
|
/** Function to add a face to the mesh and initializing it with the three given coords
|
||||||
|
|
@ -810,7 +821,6 @@ public:
|
||||||
assert((int)pos==m.vn);
|
assert((int)pos==m.vn);
|
||||||
|
|
||||||
PermutateVertexVector(m, pu);
|
PermutateVertexVector(m, pu);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \brief Wrapper without the PointerUpdater. */
|
/*! \brief Wrapper without the PointerUpdater. */
|
||||||
|
|
@ -868,7 +878,7 @@ public:
|
||||||
m.edge[ pu.remap[i] ].VEi(1) = m.edge[i].cVEi(1);
|
m.edge[ pu.remap[i] ].VEi(1) = m.edge[i].cVEi(1);
|
||||||
}
|
}
|
||||||
if(HasEEAdjacency(m))
|
if(HasEEAdjacency(m))
|
||||||
if (m.edge[i].cEEp(0)!=0)
|
// if (m.edge[i].cEEp(0)!=0)
|
||||||
{
|
{
|
||||||
m.edge[ pu.remap[i] ].EEp(0) = m.edge[i].cEEp(0);
|
m.edge[ pu.remap[i] ].EEp(0) = m.edge[i].cEEp(0);
|
||||||
m.edge[ pu.remap[i] ].EEi(0) = m.edge[i].cEEi(0);
|
m.edge[ pu.remap[i] ].EEi(0) = m.edge[i].cEEi(0);
|
||||||
|
|
|
||||||
|
|
@ -217,7 +217,7 @@ namespace vcg
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t serialize(std::string& str)
|
size_t serialize(std::string& str) const
|
||||||
{
|
{
|
||||||
for (unsigned int ii = 0; ii < ATT_NAMES_DERIVED_CLASS::enumArity(); ++ii)
|
for (unsigned int ii = 0; ii < ATT_NAMES_DERIVED_CLASS::enumArity(); ++ii)
|
||||||
str.append(((_atts[ii]) ? "1" : "0"));
|
str.append(((_atts[ii]) ? "1" : "0"));
|
||||||
|
|
|
||||||
|
|
@ -263,10 +263,10 @@ namespace vcg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void serialize(std::string& str)
|
void serialize(std::string& str) const
|
||||||
{
|
{
|
||||||
str.append(_pmmask.to_string());
|
str.append(_pmmask.to_string());
|
||||||
for (typename PerRendModData::iterator it = _intatts.begin(); it != _intatts.end(); ++it)
|
for (typename PerRendModData::const_iterator it = _intatts.begin(); it != _intatts.end(); ++it)
|
||||||
{
|
{
|
||||||
std::string s;
|
std::string s;
|
||||||
it->serialize(s);
|
it->serialize(s);
|
||||||
|
|
@ -295,7 +295,8 @@ namespace vcg
|
||||||
}
|
}
|
||||||
if (_glopts != NULL)
|
if (_glopts != NULL)
|
||||||
{
|
{
|
||||||
int size = _glopts->serialize(std::string());
|
std::string tmp;
|
||||||
|
int size = _glopts->serialize(tmp);
|
||||||
token[i] = str.substr(pos, size);
|
token[i] = str.substr(pos, size);
|
||||||
if (token[i].length() < size)
|
if (token[i].length() < size)
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -369,7 +369,7 @@ public:
|
||||||
AddBorderConstraints(mesh);
|
AddBorderConstraints(mesh);
|
||||||
|
|
||||||
//aff final constraints
|
//aff final constraints
|
||||||
for (int i=0;i<SParam.AddConstr.size();i++)
|
for (size_t i=0;i<SParam.AddConstr.size();i++)
|
||||||
{
|
{
|
||||||
int indexF=SParam.AddConstr[i].first;
|
int indexF=SParam.AddConstr[i].first;
|
||||||
CoordType dir=SParam.AddConstr[i].second;
|
CoordType dir=SParam.AddConstr[i].second;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue