Small changes in the long long way to making meshlab and the vcglib really float/double independent
TexCoordScalarType can be different from the mesh scalar type
This commit is contained in:
parent
f9fbb89854
commit
0970bd18ca
|
@ -8,7 +8,7 @@
|
||||||
* \ *
|
* \ *
|
||||||
* All rights reserved. *
|
* All rights reserved. *
|
||||||
* *
|
* *
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
* it under the terms of the GNU General Public License as published by *
|
* it under the terms of the GNU General Public License as published by *
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
* (at your option) any later version. *
|
* (at your option) any later version. *
|
||||||
|
@ -26,248 +26,249 @@
|
||||||
#include <vcg/complex/algorithms/parametrization/uv_utils.h>
|
#include <vcg/complex/algorithms/parametrization/uv_utils.h>
|
||||||
|
|
||||||
namespace vcg {
|
namespace vcg {
|
||||||
namespace tri{
|
namespace tri{
|
||||||
template <class MeshType, bool PerWedgeFlag>
|
template <class MeshType, bool PerWedgeFlag>
|
||||||
class Distortion
|
class Distortion
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef typename MeshType::FaceType FaceType;
|
typedef typename MeshType::FaceType FaceType;
|
||||||
typedef typename MeshType::VertexType VertexType;
|
typedef typename MeshType::VertexType VertexType;
|
||||||
typedef typename MeshType::CoordType CoordType;
|
typedef typename MeshType::CoordType CoordType;
|
||||||
typedef typename MeshType::ScalarType ScalarType;
|
typedef typename MeshType::ScalarType ScalarType;
|
||||||
|
typedef typename MeshType::FaceType::TexCoordType::ScalarType TexScalarType;
|
||||||
|
|
||||||
static ScalarType Area3D(const FaceType *f)
|
static ScalarType Area3D(const FaceType *f)
|
||||||
{
|
{
|
||||||
return DoubleArea(*f)*(0.5);
|
return DoubleArea(*f)*(0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ScalarType AreaUV(const FaceType *f)
|
static ScalarType AreaUV(const FaceType *f)
|
||||||
{
|
{
|
||||||
Point2<ScalarType> uv0,uv1,uv2;
|
Point2<TexScalarType> uv0,uv1,uv2;
|
||||||
if(PerWedgeFlag) {
|
if(PerWedgeFlag) {
|
||||||
uv0=f->cWT(0).P();
|
uv0=f->cWT(0).P();
|
||||||
uv1=f->cWT(1).P();
|
uv1=f->cWT(1).P();
|
||||||
uv2=f->cWT(2).P();
|
uv2=f->cWT(2).P();
|
||||||
} else {
|
} else {
|
||||||
uv0=f->cV(0)->T().P();
|
uv0=f->cV(0)->T().P();
|
||||||
uv1=f->cV(1)->T().P();
|
uv1=f->cV(1)->T().P();
|
||||||
uv2=f->cV(2)->T().P();
|
uv2=f->cV(2)->T().P();
|
||||||
}
|
}
|
||||||
ScalarType AreaUV=((uv1-uv0)^(uv2-uv0))/2.0;
|
ScalarType AreaUV=((uv1-uv0)^(uv2-uv0))/2.0;
|
||||||
return AreaUV;
|
return AreaUV;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ScalarType EdgeLenght3D(const FaceType *f,int e)
|
static ScalarType EdgeLenght3D(const FaceType *f,int e)
|
||||||
{
|
{
|
||||||
assert((e>=0)&&(e<3));
|
assert((e>=0)&&(e<3));
|
||||||
ScalarType length=(f->cP0(e)-f->cP1(e)).Norm();
|
ScalarType length=(f->cP0(e)-f->cP1(e)).Norm();
|
||||||
return (length);
|
return (length);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ScalarType EdgeLenghtUV(const FaceType *f,int e)
|
static ScalarType EdgeLenghtUV(const FaceType *f,int e)
|
||||||
{
|
{
|
||||||
assert((e>=0)&&(e<3));
|
assert((e>=0)&&(e<3));
|
||||||
Point2<ScalarType> uv0,uv1;
|
Point2<TexScalarType> uv0,uv1;
|
||||||
if(PerWedgeFlag) {
|
if(PerWedgeFlag) {
|
||||||
uv0=f->cWT(e+0).P();
|
uv0=f->cWT(e+0).P();
|
||||||
uv1=f->cWT((e+1)%3).P();
|
uv1=f->cWT((e+1)%3).P();
|
||||||
} else {
|
} else {
|
||||||
uv0=f->cV0(e)->T().P();
|
uv0=f->cV0(e)->T().P();
|
||||||
uv1=f->cV1(e)->T().P();
|
uv1=f->cV1(e)->T().P();
|
||||||
}
|
}
|
||||||
ScalarType UVlength=Distance(uv0,uv1);
|
ScalarType UVlength=Distance(uv0,uv1);
|
||||||
return UVlength;
|
return UVlength;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ScalarType AngleCos3D(const FaceType *f,int e)
|
static ScalarType AngleCos3D(const FaceType *f,int e)
|
||||||
{
|
{
|
||||||
assert((e>=0)&&(e<3));
|
assert((e>=0)&&(e<3));
|
||||||
CoordType p0=f->P((e+2)%3);
|
CoordType p0=f->P((e+2)%3);
|
||||||
CoordType p1=f->P(e);
|
CoordType p1=f->P(e);
|
||||||
CoordType p2=f->P((e+1)%3);
|
CoordType p2=f->P((e+1)%3);
|
||||||
typedef typename CoordType::ScalarType ScalarType;
|
typedef typename CoordType::ScalarType ScalarType;
|
||||||
CoordType dir0=p2-p1;
|
CoordType dir0=p2-p1;
|
||||||
CoordType dir1=p0-p1;
|
CoordType dir1=p0-p1;
|
||||||
dir0.Normalize();
|
dir0.Normalize();
|
||||||
dir1.Normalize();
|
dir1.Normalize();
|
||||||
ScalarType angle=dir0*dir1;
|
ScalarType angle=dir0*dir1;
|
||||||
return angle;
|
return angle;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ScalarType AngleCosUV(const FaceType *f,int e)
|
static ScalarType AngleCosUV(const FaceType *f,int e)
|
||||||
{
|
{
|
||||||
Point2<ScalarType> uv0,uv1,uv2;
|
Point2<ScalarType> uv0,uv1,uv2;
|
||||||
if(PerWedgeFlag) {
|
if(PerWedgeFlag) {
|
||||||
uv0=f->cWT((e+2)%3).P();
|
uv0=f->cWT((e+2)%3).P();
|
||||||
uv1=f->cWT((e+0)%3).P();
|
uv1=f->cWT((e+0)%3).P();
|
||||||
uv2=f->cWT((e+1)%3).P();
|
uv2=f->cWT((e+1)%3).P();
|
||||||
} else {
|
} else {
|
||||||
uv0=f->V2(e)->T().P();
|
uv0=f->V2(e)->T().P();
|
||||||
uv1=f->V0(e)->T().P();
|
uv1=f->V0(e)->T().P();
|
||||||
uv2=f->V1(e)->T().P();
|
uv2=f->V1(e)->T().P();
|
||||||
}
|
}
|
||||||
vcg::Point2<ScalarType> dir0=uv2-uv1;
|
vcg::Point2<ScalarType> dir0=uv2-uv1;
|
||||||
vcg::Point2<ScalarType> dir1=uv0-uv1;
|
vcg::Point2<ScalarType> dir1=uv0-uv1;
|
||||||
dir0.Normalize();
|
dir0.Normalize();
|
||||||
dir1.Normalize();
|
dir1.Normalize();
|
||||||
ScalarType angle=dir0*dir1;
|
ScalarType angle=dir0*dir1;
|
||||||
return angle;
|
return angle;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ScalarType AngleRad3D(const FaceType *f,int e)
|
static ScalarType AngleRad3D(const FaceType *f,int e)
|
||||||
{
|
{
|
||||||
assert((e>=0)&&(e<3));
|
assert((e>=0)&&(e<3));
|
||||||
CoordType p0=f->cP((e+2)%3);
|
CoordType p0=f->cP((e+2)%3);
|
||||||
CoordType p1=f->cP(e);
|
CoordType p1=f->cP(e);
|
||||||
CoordType p2=f->cP((e+1)%3);
|
CoordType p2=f->cP((e+1)%3);
|
||||||
typedef typename CoordType::ScalarType ScalarType;
|
typedef typename CoordType::ScalarType ScalarType;
|
||||||
CoordType dir0=p2-p1;
|
CoordType dir0=p2-p1;
|
||||||
CoordType dir1=p0-p1;
|
CoordType dir1=p0-p1;
|
||||||
return Angle(dir0,dir1);
|
return Angle(dir0,dir1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ScalarType AngleRadUV(const FaceType *f,int e)
|
static ScalarType AngleRadUV(const FaceType *f,int e)
|
||||||
{
|
{
|
||||||
Point2<ScalarType> uv0,uv1,uv2;
|
Point2<TexScalarType> uv0,uv1,uv2;
|
||||||
if(PerWedgeFlag) {
|
if(PerWedgeFlag) {
|
||||||
uv0=f->cWT((e+2)%3).P();
|
uv0=f->cWT((e+2)%3).P();
|
||||||
uv1=f->cWT((e+0)%3).P();
|
uv1=f->cWT((e+0)%3).P();
|
||||||
uv2=f->cWT((e+1)%3).P();
|
uv2=f->cWT((e+1)%3).P();
|
||||||
} else {
|
} else {
|
||||||
uv0=f->cV2(e)->T().P();
|
uv0=f->cV2(e)->T().P();
|
||||||
uv1=f->cV0(e)->T().P();
|
uv1=f->cV0(e)->T().P();
|
||||||
uv2=f->cV1(e)->T().P();
|
uv2=f->cV1(e)->T().P();
|
||||||
}
|
}
|
||||||
vcg::Point2<ScalarType> dir0=uv2-uv1;
|
vcg::Point2<TexScalarType> dir0=uv2-uv1;
|
||||||
vcg::Point2<ScalarType> dir1=uv0-uv1;
|
vcg::Point2<TexScalarType> dir1=uv0-uv1;
|
||||||
dir0.Normalize();
|
dir0.Normalize();
|
||||||
dir1.Normalize();
|
dir1.Normalize();
|
||||||
ScalarType t=dir0*dir1;
|
ScalarType t=dir0*dir1;
|
||||||
if(t>1) t = 1;
|
if(t>1) t = 1;
|
||||||
else if(t<-1) t = -1;
|
else if(t<-1) t = -1;
|
||||||
return acos(t);
|
return acos(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum DistType{AreaDist,EdgeDist,AngleDist};
|
enum DistType{AreaDist,EdgeDist,AngleDist};
|
||||||
|
|
||||||
///return the absolute difference between angle in 3D space and texture space
|
///return the absolute difference between angle in 3D space and texture space
|
||||||
///Actually the difference in cos space
|
///Actually the difference in cos space
|
||||||
static ScalarType AngleCosDistortion(const FaceType *f,int e)
|
static ScalarType AngleCosDistortion(const FaceType *f,int e)
|
||||||
{
|
{
|
||||||
ScalarType Angle_3D=AngleCos3D(f,e);
|
ScalarType Angle_3D=AngleCos3D(f,e);
|
||||||
ScalarType Angle_UV=AngleCosUV(f,e);
|
ScalarType Angle_UV=AngleCosUV(f,e);
|
||||||
ScalarType diff=fabs(Angle_3D-Angle_UV);///Angle_3D;
|
ScalarType diff=fabs(Angle_3D-Angle_UV);///Angle_3D;
|
||||||
return diff;
|
return diff;
|
||||||
}
|
}
|
||||||
///return the absolute difference between angle in 3D space and texture space
|
///return the absolute difference between angle in 3D space and texture space
|
||||||
///Actually the difference in cos space
|
///Actually the difference in cos space
|
||||||
static ScalarType AngleRadDistortion(const FaceType *f,int e)
|
static ScalarType AngleRadDistortion(const FaceType *f,int e)
|
||||||
{
|
{
|
||||||
ScalarType Angle_3D=AngleRad3D(f,e);
|
ScalarType Angle_3D=AngleRad3D(f,e);
|
||||||
ScalarType Angle_UV=AngleRadUV(f,e);
|
ScalarType Angle_UV=AngleRadUV(f,e);
|
||||||
ScalarType diff=fabs(Angle_3D-Angle_UV);///Angle_3D;
|
ScalarType diff=fabs(Angle_3D-Angle_UV);///Angle_3D;
|
||||||
return diff;
|
return diff;
|
||||||
}
|
}
|
||||||
|
|
||||||
///return the variance of angle, normalized
|
///return the variance of angle, normalized
|
||||||
///in absolute value
|
///in absolute value
|
||||||
static ScalarType AngleDistortion(const FaceType *f)
|
static ScalarType AngleDistortion(const FaceType *f)
|
||||||
{
|
{
|
||||||
return AngleRadDistortion(f,0) +
|
return AngleRadDistortion(f,0) +
|
||||||
AngleRadDistortion(f,1) +
|
AngleRadDistortion(f,1) +
|
||||||
AngleRadDistortion(f,2);
|
AngleRadDistortion(f,2);
|
||||||
}
|
}
|
||||||
|
|
||||||
///return the global scaling factors from 3D to UV
|
///return the global scaling factors from 3D to UV
|
||||||
static void MeshScalingFactor(const MeshType &m,
|
static void MeshScalingFactor(const MeshType &m,
|
||||||
ScalarType &AreaScale,
|
ScalarType &AreaScale,
|
||||||
ScalarType &EdgeScale)
|
ScalarType &EdgeScale)
|
||||||
{
|
{
|
||||||
ScalarType SumArea3D=0;
|
ScalarType SumArea3D=0;
|
||||||
ScalarType SumArea2D=0;
|
ScalarType SumArea2D=0;
|
||||||
ScalarType SumEdge3D=0;
|
ScalarType SumEdge3D=0;
|
||||||
ScalarType SumEdge2D=0;
|
ScalarType SumEdge2D=0;
|
||||||
for (int i=0;i<m.face.size();i++)
|
for (int i=0;i<m.face.size();i++)
|
||||||
{
|
{
|
||||||
SumArea3D+=Area3D(&m.face[i]);
|
SumArea3D+=Area3D(&m.face[i]);
|
||||||
SumArea2D+=AreaUV(&m.face[i]);
|
SumArea2D+=AreaUV(&m.face[i]);
|
||||||
for (int j=0;j<3;j++)
|
for (int j=0;j<3;j++)
|
||||||
{
|
{
|
||||||
SumEdge3D+=EdgeLenght3D(&m.face[i],j);
|
SumEdge3D+=EdgeLenght3D(&m.face[i],j);
|
||||||
SumEdge2D+=EdgeLenghtUV(&m.face[i],j);
|
SumEdge2D+=EdgeLenghtUV(&m.face[i],j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AreaScale=SumArea3D/SumArea2D;
|
AreaScale=SumArea3D/SumArea2D;
|
||||||
EdgeScale=SumEdge3D/SumEdge2D;
|
EdgeScale=SumEdge3D/SumEdge2D;
|
||||||
}
|
}
|
||||||
|
|
||||||
///return the variance of edge length, normalized in absolute value,
|
///return the variance of edge length, normalized in absolute value,
|
||||||
// the needed scaling factor EdgeScaleVal may be calculated
|
// the needed scaling factor EdgeScaleVal may be calculated
|
||||||
///by using the ScalingFactor function
|
///by using the ScalingFactor function
|
||||||
static ScalarType EdgeDistortion(const FaceType *f,int e,
|
static ScalarType EdgeDistortion(const FaceType *f,int e,
|
||||||
ScalarType EdgeScaleVal)
|
ScalarType EdgeScaleVal)
|
||||||
{
|
{
|
||||||
ScalarType edgeUV=EdgeLenghtUV(f,e)*EdgeScaleVal;
|
ScalarType edgeUV=EdgeLenghtUV(f,e)*EdgeScaleVal;
|
||||||
ScalarType edge3D=EdgeLenght3D(f,e);
|
ScalarType edge3D=EdgeLenght3D(f,e);
|
||||||
assert(edge3D > 0);
|
assert(edge3D > 0);
|
||||||
ScalarType diff=fabs(edge3D-edgeUV)/edge3D;
|
ScalarType diff=fabs(edge3D-edgeUV)/edge3D;
|
||||||
assert(!math::IsNAN(diff));
|
assert(!math::IsNAN(diff));
|
||||||
return diff;
|
return diff;
|
||||||
}
|
}
|
||||||
|
|
||||||
///return the variance of area, normalized
|
///return the variance of area, normalized
|
||||||
///in absolute value, the scalar AreaScaleVal may be calculated
|
///in absolute value, the scalar AreaScaleVal may be calculated
|
||||||
///by using the ScalingFactor function
|
///by using the ScalingFactor function
|
||||||
static ScalarType AreaDistortion(const FaceType *f,
|
static ScalarType AreaDistortion(const FaceType *f,
|
||||||
ScalarType AreaScaleVal)
|
ScalarType AreaScaleVal)
|
||||||
{
|
{
|
||||||
ScalarType areaUV=AreaUV(f)*AreaScaleVal;
|
ScalarType areaUV=AreaUV(f)*AreaScaleVal;
|
||||||
ScalarType area3D=Area3D(f);
|
ScalarType area3D=Area3D(f);
|
||||||
assert(area3D > 0);
|
assert(area3D > 0);
|
||||||
ScalarType diff=fabs(areaUV-area3D)/area3D;
|
ScalarType diff=fabs(areaUV-area3D)/area3D;
|
||||||
assert(!math::IsNAN(diff));
|
assert(!math::IsNAN(diff));
|
||||||
return diff;
|
return diff;
|
||||||
}
|
}
|
||||||
|
|
||||||
///return the number of folded faces
|
///return the number of folded faces
|
||||||
static bool Folded(const FaceType *f)
|
static bool Folded(const FaceType *f)
|
||||||
{
|
{
|
||||||
ScalarType areaUV=AreaUV(f);
|
ScalarType areaUV=AreaUV(f);
|
||||||
/*if (areaUV<0)
|
/*if (areaUV<0)
|
||||||
printf("area %5.5f \n",areaUV);*/
|
printf("area %5.5f \n",areaUV);*/
|
||||||
return (areaUV<0);
|
return (areaUV<0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int Folded(const MeshType &m)
|
static int Folded(const MeshType &m)
|
||||||
{
|
{
|
||||||
int folded=0;
|
int folded=0;
|
||||||
for (size_t i=0;i<m.face.size();i++)
|
for (size_t i=0;i<m.face.size();i++)
|
||||||
{
|
{
|
||||||
if (m.face[i].IsD())continue;
|
if (m.face[i].IsD())continue;
|
||||||
if(Folded(&m.face[i]))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=Folded(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 (int i=0;i<m.face.size();i++)
|
for (int i=0;i<m.face.size();i++)
|
||||||
{
|
{
|
||||||
if (m.face[i].IsD())continue;
|
if (m.face[i].IsD())continue;
|
||||||
const FaceType *f=&(m.face[i]);
|
const FaceType *f=&(m.face[i]);
|
||||||
UDdist+=AngleDistortion(f)*Area3D(f);
|
UDdist+=AngleDistortion(f)*Area3D(f);
|
||||||
}
|
}
|
||||||
return UDdist;
|
return UDdist;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SetQasDistorsion(MeshType &m,
|
static void SetQasDistorsion(MeshType &m,
|
||||||
DistType DType=AreaDist)
|
DistType DType=AreaDist)
|
||||||
|
@ -288,7 +289,7 @@ namespace vcg {
|
||||||
EdgeDistortion(&m.face[i],2,edge_scale);
|
EdgeDistortion(&m.face[i],2,edge_scale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue