Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef VCG_UV_UTILS
00025 #define VCG_UV_UTILS
00026
00027
00028 namespace vcg {
00029 namespace tri{
00030 template <class MeshType>
00031 class UV_Utils
00032 {
00033 typedef typename MeshType::CoordType CoordType;
00034 typedef typename MeshType::ScalarType ScalarType;
00035 typedef typename MeshType::FaceType FaceType;
00036 typedef typename MeshType::VertexType VertexType;
00037 typedef typename MeshType::VertexIterator VertexIterator;
00038 typedef typename MeshType::FaceIterator FaceIterator;
00039 typedef typename vcg::Point2<ScalarType> UVCoordType;
00040
00041 public:
00043 static vcg::Box2<ScalarType> PerWedgeUVBox(MeshType &m)
00044 {
00045 vcg::Box2<ScalarType> UVBox;
00046 FaceIterator fi;
00047 for (fi=m.face.begin();fi!=m.face.end();fi++)
00048 {
00049 if ((*fi).IsD()) continue;
00050 for (int i=0;i<3;i++)
00051 UVBox.Add((*fi).WT(i).P());
00052 }
00053 return UVBox;
00054 }
00055
00057 static vcg::Box2<ScalarType> PerVertUVBox(MeshType &m)
00058 {
00059 vcg::Box2<ScalarType> UVBox;
00060 VertexIterator vi;
00061 for (vi=m.vert.begin();vi!=m.vert.end();vi++)
00062 {
00063 if ((*vi).IsD()) continue;
00064 UVBox.Add((*vi).T().P());
00065 }
00066 return UVBox;
00067 }
00068
00069 void PerWedgeMakeUnitaryUV(MeshType &m)
00070 {
00071 vcg::Box2<typename MeshType::ScalarType> UVBox = PerWedgeUVBox(m);
00072
00073 typename MeshType::FaceIterator fi;
00074 Point2f boxSize(UVBox.max-UVBox.min);
00075 for (fi=m.face.begin();fi!=m.face.end();fi++)
00076 {
00077 if ((*fi).IsD()) continue;
00078 for (int i=0;i<3;i++)
00079 {
00080 (*fi).WT(i).U() = ((*fi).WT(i).U()-UVBox.min[0])/boxSize[0] ;
00081 (*fi).WT(i).V() = ((*fi).WT(i).V()-UVBox.min[1])/boxSize[1] ;
00082 }
00083 }
00084 }
00086 static UVCoordType Coord3DtoUV(FaceType &f,const CoordType &dir)
00087 {
00089 CoordType bary3d=(f.P(0)+f.P(1)+f.P(2))/3.0;
00090 UVCoordType baryUV=(f.WT(0).P()+f.WT(1).P()+f.WT(2).P())/3.0;
00091 CoordType dir3d=bary3d+dir;
00092 CoordType baryCoordsUV;
00093 vcg::InterpolationParameters<FaceType,ScalarType>(f,dir3d,baryCoordsUV);
00094 UVCoordType dirUV=baryCoordsUV.X()*f.WT(0).P()+
00095 baryCoordsUV.Y()*f.WT(1).P()+
00096 baryCoordsUV.Z()*f.WT(2).P()-baryUV;
00097 dirUV.Normalize();
00098 return dirUV;
00099 }
00100
00101 static void GloballyMirrorX(MeshType &m)
00102 {
00103 vcg::Box2<ScalarType> BBuv=PerVertUVBox(m);
00104 ScalarType Xmin=BBuv.min.X();
00105 ScalarType Xmax=BBuv.max.X();
00106 ScalarType XAv=(Xmax+Xmin)/2;
00107 VertexIterator vi;
00108 for (vi=m.vert.begin();vi!=m.vert.end();vi++)
00109 {
00110 ScalarType distAV=(*vi).T().P().X()-XAv;
00111 (*vi).T().P().X()=XAv-distAV;
00112 }
00113 }
00114
00115 static void LaplacianUVVert(MeshType &m,bool fix_borders=false,int steps=3)
00116 {
00117 FaceIterator fi;
00118 for (int s=0;s<steps;s++)
00119 {
00120 std::vector<int> num(m.vert.size(),0);
00121 std::vector<UVCoordType> UVpos(m.vert.size(),UVCoordType(0,0));
00122 for (fi=m.face.begin();fi!=m.face.end();fi++)
00123 {
00124 for (int j=0;j<3;j++)
00125 {
00126 VertexType *v0=(*fi).V(0);
00127 VertexType *v1=(*fi).V1(0);
00128 VertexType *v2=(*fi).V2(0);
00129 assert(v0!=v1);
00130 assert(v1!=v2);
00131 assert(v0!=v2);
00132 UVCoordType uv1=v1->T().P();
00133 UVCoordType uv2=v2->T().P();
00134 int index=v0-&(m.vert[0]);
00135 num[index]+=2;
00136 UVpos[index]+=uv1;
00137 UVpos[index]+=uv2;
00138 }
00139 }
00140 VertexIterator vi;
00141 for (int i=0;i<m.vert.size();i++)
00142 {
00143 if ((fix_borders)&&(m.vert[i].IsB()))continue;
00144 if (num[i]==0)continue;
00145 m.vert[i].T().P()=UVpos[i]/(ScalarType)num[i];
00146 }
00147 }
00148 }
00149
00150 static void CopyVertUVWedge(MeshType &m)
00151 {
00152 for (size_t i=0;i<m.face.size();i++)
00153 for (size_t j=0;j<3;j++)
00154 m.face[i].WT(j).P()=m.face[i].V(j)->T().P();
00155 }
00156
00157 static void CopyWedgeVertUV(MeshType &m,bool onlyS=false)
00158 {
00159 for (size_t i=0;i<m.face.size();i++)
00160 {
00161 if ((onlyS)&&(!m.face[i].IsS()))continue;
00162 for (int j=0;j<3;j++)
00163 m.face[i].V(j)->T().P()=m.face[i].WT(j).P();
00164 }
00165 }
00166 };
00167 }
00168 }
00169 #endif