Updated the whole isoparametrization framework to the new local optimization framework by flipping to the new local optimization framework.

This commit is contained in:
Paolo Cignoni cignoni 2011-06-16 14:48:23 +00:00
parent 17b67c129f
commit b0c8146df4
9 changed files with 118 additions and 107 deletions

View File

@ -267,7 +267,7 @@ public:
{
inDomain.push_back(test);
///parametrize it
GetUV<MeshType>(father,bary,test->T().U(),test->T().V());
InterpolateUV<MeshType>(father,bary,test->T().U(),test->T().V());
}
}
///create Hres mesh already parametrized
@ -333,7 +333,7 @@ public:
{
inDomain.push_back(test);
///parametrize it
GetUV<MeshType>(father,bary,test->T().U(),test->T().V());
InterpolateUV<MeshType>(father,bary,test->T().U(),test->T().V());
}
}
///create Hres mesh already parametrized
@ -388,7 +388,7 @@ public:
FaceType * father=test->father;
assert(father==f0);
CoordType bary=test->Bary;
GetUV<MeshType>(father,bary,test->T().U(),test->T().V());
InterpolateUV<MeshType>(father,bary,test->T().U(),test->T().V());
}
///create Hres mesh already parametrized
std::vector<FaceType*> OrderedFaces;
@ -659,4 +659,4 @@ public:
}
}
};
#endif
#endif

View File

@ -295,7 +295,8 @@ bool FilterIsoParametrization::applyFilter(QAction *filter, MeshDocument& md, Ri
case 3:Parametrizator.SetParameters(cb,targetAbstractMinFaceNum,tolerance,IsoParametrizator::SM_L2,convergenceSpeed);break;
default:Parametrizator.SetParameters(cb,targetAbstractMinFaceNum,tolerance,IsoParametrizator::SM_Euristic,convergenceSpeed);break;
}
IsoParametrizator::ReturnCode ret=Parametrizator.Parametrize<CMeshO>(mesh,doublestep);
tri::ParamEdgeCollapseParameter pecp;
IsoParametrizator::ReturnCode ret=Parametrizator.Parametrize<CMeshO>(mesh,pecp,doublestep);
if (ret==IsoParametrizator::Done)
{

View File

@ -844,14 +844,10 @@ private:
void Clamp(vcg::Point2f &UV)
{
float eps=0.00001f;
if ((UV.X()<eps)&&(UV.X()>-eps))
UV.X()=0;
if ((UV.X()<1+eps)&&(UV.X()>1-eps))
UV.X()=1;
if ((UV.Y()<eps)&&(UV.Y()>-eps))
UV.Y()=0;
if ((UV.Y()<1+eps)&&(UV.Y()>1-eps))
UV.Y()=1;
if (UV.X() < eps) UV.X()=0;
if (UV.X()>1-eps) UV.X()=1;
if (UV.Y() < eps) UV.Y()=0;
if (UV.Y()>1-eps) UV.Y()=1;
}
@ -1218,7 +1214,7 @@ public:
vcg::Point2<ScalarType> UV_interp=bary3D.X()*UVd0+bary3D.Y()*UVd1+bary3D.Z()*UVd2;
inv_GE1(EdgeIndex,UV_interp,I,UV);
Clamp(UV);
assert((UV.X()>=0)&&(UV.Y()>=0)&&(UV.X()<=1)&&(UV.Y()<=1)&&(UV.X()+UV.Y()<=1+eps));
//assert((UV.X()>=0)&&(UV.Y()>=0)&&(UV.X()<=1)&&(UV.Y()<=1)&&(UV.X()+UV.Y()<=1+eps));
assert((I==I0)||(I==I1)||(I==I2));
return;
}
@ -1351,7 +1347,7 @@ public:
if (LocalIndex==-1)
return false;
GetUV<AbstractMesh>(&star_domain->face[LocalIndex],bary,UVHstar.X(),UVHstar.Y());
InterpolateUV<AbstractMesh>(&star_domain->face[LocalIndex],bary,UVHstar.X(),UVHstar.Y());
return true;
}
@ -1407,7 +1403,7 @@ public:
int LocalIndex=diamond_meshes[DiamIndex].Global2Local(I);
if(LocalIndex!=-1)
{
GetUV<AbstractMesh>(&diam_domain->face[LocalIndex],bary,UVDiam.X(),UVDiam.Y());
InterpolateUV<AbstractMesh>(&diam_domain->face[LocalIndex],bary,UVDiam.X(),UVDiam.Y());
return;
}
///if ! found seach in the star space

View File

@ -86,7 +86,7 @@ typename MeshType::ScalarType StarDistorsion(typename MeshType::VertexType *v)
///interpolate U V per vertex
CoordType bary=test_face->vertices_bary[i].second;
ScalarType u,v;
GetUV<MeshType>(parametric_face,bary,u,v);
InterpolateUV<MeshType>(parametric_face,bary,u,v);
VertexType* to_parametrize=test_face->vertices_bary[i].first;
to_parametrize->T().U()=u;
@ -145,7 +145,7 @@ void OptimizeStar(typename MeshType::VertexType *v,MeshType &domain,int accuracy
///interpolate U V per vertex
CoordType bary=test_face->vertices_bary[i].second;
ScalarType u,v;
GetUV<MeshType>(parametric_face,bary,u,v);
InterpolateUV<MeshType>(parametric_face,bary,u,v);
VertexType* to_parametrize=test_face->vertices_bary[i].first;
to_parametrize->T().U()=u;

View File

@ -763,7 +763,9 @@ bool testBaryCoords(CoordType &bary)
template <class CoordType>
bool NormalizeBaryCoords(CoordType &bary)
{
ScalarType EPS=(ScalarType)0.00000001;
typedef typename CoordType::ScalarType ScalarType;
ScalarType EPS=(ScalarType)0.00000001;
bool isOK=testBaryCoords(bary);
if (!isOK)
return false;
@ -771,20 +773,14 @@ bool NormalizeBaryCoords(CoordType &bary)
typedef typename CoordType::ScalarType ScalarType;
///test <0
if (bary.X()<0)
bary.X()=EPS;
if (bary.Y()<0)
bary.Y()=EPS;
if (bary.Z()<0)
bary.Z()=EPS;
if (bary.X()<0) bary.X()=EPS;
if (bary.Y()<0) bary.Y()=EPS;
if (bary.Z()<0) bary.Z()=EPS;
///test >1
if (bary.X()>1.0)
bary.X()=EPS;
if (bary.Y()>1.0)
bary.Y()=EPS;
if (bary.Z()>1.0)
bary.Z()=EPS;
if (bary.X()>1.0) bary.X()=1.0-EPS;
if (bary.Y()>1.0) bary.Y()=1.0-EPS;
if (bary.Z()>1.0) bary.Z()=1.0-EPS;
///test sum
ScalarType diff=bary.X()+bary.Y()+bary.Z()-1.0;
@ -799,7 +795,7 @@ template <class MeshType>
void AssingFather(typename MeshType::VertexType &v,
typename MeshType::FaceType *father,
typename MeshType::CoordType &bary,
MeshType & domain)
MeshType & /*domain*/)
{
#ifdef _DEBUG
const typename MeshType::ScalarType eps=(typename MeshType::ScalarType)0.00001;
@ -818,8 +814,7 @@ void AssingFather(typename MeshType::VertexType &v,
template <class MeshType>
bool testParametrization(MeshType &domain,
MeshType &Hlev,
bool correct=true)
MeshType &Hlev)
{
typedef typename MeshType::FaceType FaceType;
typedef typename MeshType::CoordType CoordType;
@ -1164,7 +1159,7 @@ void ParametrizeLocally(MeshType &parametrized,
template <class MeshType>
void GetUV(const typename MeshType::FaceType* f,
void InterpolateUV(const typename MeshType::FaceType* f,
const typename MeshType::CoordType &bary,
typename MeshType::ScalarType &U,
typename MeshType::ScalarType &V)
@ -1430,7 +1425,7 @@ void ParametrizeStarEquilateral(typename MeshType::VertexType *center,
{
FaceType *father=HresVert[i]->father;
CoordType Bary=HresVert[i]->Bary;
GetUV<MeshType>(father,Bary,HresVert[i]->T().U(),HresVert[i]->T().V());
InterpolateUV<MeshType>(father,Bary,HresVert[i]->T().U(),HresVert[i]->T().V());
}
}

View File

@ -20,10 +20,28 @@
#include "opt_patch.h"
#include "local_optimization.h"
template <class BaseMesh>
class ParamEdgeCollapse: public vcg::tri::TriEdgeCollapse<BaseMesh,ParamEdgeCollapse<BaseMesh> > {
namespace vcg{
namespace tri{
typedef vcg::tri::BasicVertexPair<BaseMesh::VertexType> VertexPair;
class ParamEdgeCollapseParameter : public vcg::BaseParameterClass
{
private:
EnergyType E;
int _acc;
BaseMesh* mesh;
public:
typedef vcg::tri::TriEdgeCollapse<BaseMesh,ParamEdgeCollapse<BaseMesh> > Super;
int &Accuracy() { return _acc;}
BaseMesh* &HresMesh() { return mesh; }
EnergyType &EType() { return E; }
};
template <class BaseMesh>
class ParamEdgeCollapse: public vcg::tri::TriEdgeCollapse<BaseMesh, VertexPair , ParamEdgeCollapse<BaseMesh> > {
public:
typedef vcg::tri::TriEdgeCollapse<BaseMesh, VertexPair, ParamEdgeCollapse<BaseMesh> > Super;
typedef typename BaseMesh::VertexType::EdgeType EdgeType;
typedef typename BaseMesh::VertexType VertexType;
typedef typename BaseMesh::VertexType BaseVertex;
@ -33,13 +51,12 @@ public:
typedef typename BaseMesh::CoordType CoordType;
typedef BaseMesh TriMeshType;
static EnergyType &EType(){static EnergyType E;return E;};
inline ParamEdgeCollapse(const EdgeType &p, int mark)
inline ParamEdgeCollapse(const VertexPair &p, int mark, BaseParameterClass *pp)
{
Super::localMark = mark;
Super::pos=p;
Super::_priority = ComputePriority();
Super::_priority = ComputePriority(pp);
}
inline ScalarType Cost()
@ -59,8 +76,9 @@ public:
return (pow(lenght,2)+costArea);
}
inline bool IsFeasible(){
return LinkConditions(Super::pos);
inline bool IsFeasible(const BaseParameterClass *){
// return LinkConditions(Super::pos);
return EdgeCollapser<TriMeshType,VertexPair>::LinkConditions(Super::pos);
}
inline void SetHlevMeshUV(const std::vector<BaseFace*> &LowFace,
@ -77,7 +95,7 @@ public:
{
VertexType *brother=test_face->vertices_bary[i].first;
CoordType bary=test_face->vertices_bary[i].second;
GetUV<BaseMesh>(test_face,bary,brother->T().U(),brother->T().V());
InterpolateUV<BaseMesh>(test_face,bary,brother->T().U(),brother->T().V());
//printf("%f , %f \n",brother->T().U(),brother->T().V());
assert(brother!=NULL);
HiVertex.push_back(brother);
@ -210,7 +228,7 @@ public:
///DISTORSION
///create pos
EdgeType posEdge;
VertexPair posEdge;
std::vector<typename FaceType::VertexType*> vertEdge;
FindNotBorderVertices<BaseMesh>(created,vertEdge);
@ -225,8 +243,8 @@ public:
for (unsigned int i=0;i<created.face.size();i++)
domain.face[i].areadelta=created.face[i].areadelta;
DoCollapse(created,posEdge, newPos); // v0 is deleted and v1 take the new position
// DoCollapse(created,posEdge, newPos); // v0 is deleted and v1 take the new position
EdgeCollapser<BaseMesh,VertexPair>::Do(created, posEdge, newPos);
UpdateTopologies<BaseMesh>(&created);
/////parametrize domain
@ -279,7 +297,7 @@ public:
return (bestPos);
}
inline ScalarType ComputePriority()
inline ScalarType ComputePriority(BaseParameterClass *)
{
return (Cost());
//return( Distance(pos.V(0)->cP(),pos.V(1)->cP()));
@ -291,7 +309,7 @@ public:
return bestPos;
}
void UpdateFF(EdgeType &posEdge)
void UpdateFF(VertexPair &posEdge)
{
std::vector<typename TriMeshType::FaceType*> shared;
std::vector<typename TriMeshType::FaceType*> in_v0;
@ -362,7 +380,7 @@ public:
///create a copy the submesh for a collapse and parameterize it
void CreatePreCollapseSubmesh(EdgeType &pos,
void CreatePreCollapseSubmesh(VertexPair &pos,
BaseMesh &param,
std::vector<VertexType*> &orderedVertex,
std::vector<FaceType*> &orderedFaces)
@ -386,7 +404,7 @@ void CreatePreCollapseSubmesh(EdgeType &pos,
///create a copy the submesh after the collapse that is already parameterized
/// only the central vertex has to be set to (0,0)
void CreatePostCollapseSubmesh(EdgeType &pos,
void CreatePostCollapseSubmesh(VertexPair &pos,
BaseMesh &param_post,
std::vector<VertexType*> &orderedVertex,
std::vector<FaceType*> &orderedFaces)
@ -413,7 +431,7 @@ void CreatePostCollapseSubmesh(EdgeType &pos,
}
void AphaBetaToUV(EdgeType &pos,
void AphaBetaToUV(VertexPair &pos,
std::vector<FaceType*> &orderedFaces,
BaseMesh &param,
std::vector<VertexType*> &HresVert)
@ -438,7 +456,7 @@ void AphaBetaToUV(EdgeType &pos,
///transform to UV
ScalarType u,v;
GetUV<BaseMesh>(parametric_face,bary,u,v);
InterpolateUV<BaseMesh>(parametric_face,bary,u,v);
///and assing
brother->T().U()=u;
brother->T().V()=v;
@ -534,7 +552,7 @@ void UVToAlphaBeta(std::vector<VertexType*> &HresVert,
brother->Bary=bary1;*/
///set new parametrization value
GetUV<BaseMesh>(&param.face[index],bary1,u,v);
InterpolateUV<BaseMesh>(&param.face[index],bary1,u,v);
HresVert[i]->T().U()=u;
HresVert[i]->T().V()=v;
}
@ -573,13 +591,15 @@ void AssignRPos(VertexType* &to_assign,
to_assign->RPos=val;
}
void Execute(BaseMesh &m)
void Execute(BaseMesh &m, vcg::BaseParameterClass *_pp)
{
typedef typename BaseMesh::FaceType FaceType;
typedef typename BaseMesh::VertexType VertexType;
typedef typename BaseMesh::ScalarType ScalarType;
typedef typename BaseMesh::CoordType CoordType;
ParamEdgeCollapseParameter *pp=(ParamEdgeCollapseParameter *)_pp;
assert(this->pos.V(0)!=this->pos.V(1));
assert(!this->pos.V(0)->IsD());
assert(!this->pos.V(1)->IsD());
@ -617,7 +637,9 @@ void Execute(BaseMesh &m)
ScalarType area0=Area<BaseFace>(orderedFaces0);
///do the collapse
DoCollapse(m, this->pos, newPos); // v0 is deleted and v1 take the new position
// DoCollapse(m, this->pos, newPos); // v0 is deleted and v1 take the new position
EdgeCollapser<TriMeshType,VertexPair>::Do(m, this->pos, newPos);
//vcg::tri::UpdateTopology<BaseMesh>::TestVertexFace(m); ///TEST
//---------------------------///
///create a parametrized submesh post-collapse #1
@ -673,24 +695,13 @@ void Execute(BaseMesh &m)
this->pos.V(1)->RPos=oldRPos;
/*bool b=*/SmartOptimizeStar<BaseMesh>(this->pos.V(1),m,Accuracy(),EType());
/*bool b=*/SmartOptimizeStar<BaseMesh>(this->pos.V(1),m,pp->Accuracy(),pp->EType());
/*int t1=clock();
time_opt+=(t1-t0);*/
}
public:
static int &Accuracy()
{
static int _acc;
return _acc;
}
static BaseMesh* &HresMesh()
{
static BaseMesh* mesh;
return mesh;
}
BaseVertex *getV(int num)
{
@ -698,5 +709,7 @@ public:
return this->pos.V(num);
}
};
}//end namespace tri
}//end namespace vcg
#endif

View File

@ -3,6 +3,9 @@
#include <vcg/complex/algorithms/local_optimization/tri_edge_flip.h>
namespace vcg{
namespace tri{
///Flip function
template <class BaseMesh>
class ParamEdgeFlip : public vcg::tri::PlanarEdgeFlip<BaseMesh, ParamEdgeFlip<BaseMesh> >
@ -19,7 +22,7 @@ class ParamEdgeFlip : public vcg::tri::PlanarEdgeFlip<BaseMesh, ParamEdgeFlip<Ba
public:
static EnergyType &EType(){static EnergyType E;return E;};
static EnergyType &EType(){static EnergyType E;return E;}
bool savedomain;
@ -36,11 +39,11 @@ class ParamEdgeFlip : public vcg::tri::PlanarEdgeFlip<BaseMesh, ParamEdgeFlip<Ba
/*!
* Constructor with <I>pos</I> type
*/
inline ParamEdgeFlip(const typename Super::PosType pos, int mark)
inline ParamEdgeFlip(const typename Super::PosType pos, int mark,BaseParameterClass *pp)
{
this->_pos = pos;
this->_localMark = mark;
this->_priority = this->ComputePriority();
this->_priority = this->ComputePriority(pp);
savedomain=false;
}
@ -71,7 +74,7 @@ class ParamEdgeFlip : public vcg::tri::PlanarEdgeFlip<BaseMesh, ParamEdgeFlip<Ba
//system("pause");
}
GetUV<BaseMesh>(father,bary,v->T().U(),v->T().V());
InterpolateUV<BaseMesh>(father,bary,v->T().U(),v->T().V());
}
///update VF topology
@ -296,7 +299,7 @@ class ParamEdgeFlip : public vcg::tri::PlanarEdgeFlip<BaseMesh, ParamEdgeFlip<Ba
time_opt+=(t1-t0);*/
}
ScalarType ComputePriority()
ScalarType ComputePriority(BaseParameterClass *)
{
this->_priority=EdgeDiff();
return this->_priority;
@ -317,4 +320,7 @@ class ParamEdgeFlip : public vcg::tri::PlanarEdgeFlip<BaseMesh, ParamEdgeFlip<Ba
};
}//end namespace tri
}//end namespace vcg
#endif

View File

@ -50,8 +50,8 @@
//int time_opt;
///Flip function
class MyTriEdgeFlip : public ParamEdgeFlip<BaseMesh>{};
class MyTriEdgeCollapse: public ParamEdgeCollapse<BaseMesh>{};
class MyTriEdgeFlip : public vcg::tri::ParamEdgeFlip<BaseMesh>{};
class MyTriEdgeCollapse: public vcg::tri::ParamEdgeCollapse<BaseMesh>{};
///THIS CLASS MAINTAINS STRUCTURES WICH ARE USED FOR PARAMETRIZATION
///TOGHETHER WITH METHOD FOR COLORIZATION FOR VISUALIZATION PURPOSES
@ -167,11 +167,9 @@ private:
////initialization for decimation
//base_mesh.en=0;
InitIMark();
for (unsigned int i=0;i<base_mesh.vert.size();i++)
base_mesh.vert[i].ClearFlags();
for (unsigned int i=0;i<base_mesh.face.size();i++)
base_mesh.face[i].ClearFlags();
InitVoronoiArea();
vcg::tri::UpdateFlags<BaseMesh>::VertexClear(base_mesh);
vcg::tri::UpdateFlags<BaseMesh>::FaceClear(base_mesh);
InitVoronoiArea();
}
void InitIMark()
@ -182,14 +180,14 @@ private:
}
void ParaDecimate(const int &targetFaces,
const int &interval,
bool execute_flip=false)
void ParaDecimate(vcg::tri::ParamEdgeCollapseParameter &pecp,
const int &targetFaces,
const int &interval,
bool execute_flip=false)
{
vcg::LocalOptimization<BaseMesh> DeciSession(base_mesh);
vcg::LocalOptimization<BaseMesh> DeciSession(base_mesh,&pecp);
DeciSession.Init<MyTriEdgeCollapse >();
MyTriEdgeCollapse::Accuracy()=accuracy;
MyTriEdgeCollapse::HresMesh()=&final_mesh;
PatchesOptimizer<BaseMesh>::HresMesh()=&final_mesh;
PatchesOptimizer<BaseMesh>::BaseMesh()=&base_mesh;
@ -269,7 +267,7 @@ private:
if (do_flip)
{
FlipStep();
FlipStep(pecp);
vcg::tri::UpdateTopology<BaseMesh>::FaceFace(base_mesh);
vcg::tri::UpdateTopology<BaseMesh>::VertexFace(base_mesh);
InitIMark();
@ -347,14 +345,12 @@ private:
{return (dist>other.dist);}
};
void FinalOptimization()
void FinalOptimization(vcg::tri::ParamEdgeCollapseParameter *pecp)
{
char ret[200];
sprintf(ret," PERFORM GLOBAL OPTIMIZATION initializing... ");
(*cb)(0,ret);
std::vector<vert_para> ord_vertex;
ord_vertex.resize(base_mesh.vn);
for (unsigned int i=0;i<base_mesh.vert.size();i++)
@ -371,7 +367,7 @@ private:
for (unsigned int i=0;i<ord_vertex.size();i++)
{
printf("%3.3f\n",ord_vertex[i].dist);
SmartOptimizeStar<BaseMesh>(ord_vertex[i].v,base_mesh,MyTriEdgeCollapse::Accuracy(),EType);
SmartOptimizeStar<BaseMesh>(ord_vertex[i].v,base_mesh,pecp->Accuracy(),EType);
}
}
@ -394,8 +390,12 @@ private:
///INITIALIZATION
InitializeStructures<MeshType>(mesh);
///DECIMATION & PARAMETRIZATION
ParaDecimate(targetFaces,interval,execute_flip);
vcg::tri::ParamEdgeCollapseParameter pecp;
pecp.Accuracy()=accuracy;
pecp.HresMesh()=&final_mesh;
///DECIMATION & PARAMETRIZATION
ParaDecimate(pecp, targetFaces,interval,execute_flip);
///SET BEST FIND STOP POINT
bool isOK=SetBestStatus(test_interpolation);
@ -407,7 +407,7 @@ private:
///LAST FLIP STEP
if (execute_flip)
FlipStep();
FlipStep(pecp);
vcg::tri::UpdateTopology<BaseMesh>::FaceFace(base_mesh);
vcg::tri::UpdateTopology<BaseMesh>::VertexFace(base_mesh);
@ -427,7 +427,7 @@ private:
///LAST OPTIMIZATION STEP ON STARS
if (execute_flip)
FinalOptimization();
FinalOptimization(&pecp);
#ifndef _MESHLAB
if (execute_flip)
@ -777,12 +777,12 @@ public:
///PARAMETRIZATION FUNCTIONS
///initialize the mesh
template <class MeshType>
ReturnCode Parametrize(MeshType *mesh,bool Two_steps=true,EnergyType _EType=EN_EXTMips)
ReturnCode Parametrize(MeshType *mesh,vcg::tri::ParamEdgeCollapseParameter &pecp,bool Two_steps=true,EnergyType _EType=EN_EXTMips)
{
EType=_EType;
MyTriEdgeCollapse::EType()=EType;
MyTriEdgeFlip::EType()=EType;
// MyTriEdgeCollapse::EType()=EType;
// MyTriEdgeFlip::EType()=EType;
pecp.EType()=_EType;
///clean unreferenced vertices
vcg::tri::Clean<MeshType>::RemoveUnreferencedVertex(*mesh);
/*bool done;*/
@ -829,7 +829,6 @@ public:
ExportMeshes(para_mesh1,abs_mesh1);
///constrauct an ISOPARAM
printf("\n STEP 2.5 \n");
IsoParametrization IsoParam1;
@ -893,7 +892,7 @@ public:
base_f->vertices_bary.push_back(std::pair<BaseVertex *,CoordType>(&final_mesh.vert[i],bary));
}
InitVoronoiArea();
FinalOptimization();
FinalOptimization(&pecp);
printf("STEP 3 \n");
}
///finally perform the final optimization step
@ -909,13 +908,13 @@ public:
}
///perform one or more flip steps
void FlipStep()
void FlipStep(vcg::tri::ParamEdgeCollapseParameter &pecp)
{
#ifndef _MESHLAB
printf("\n STARTING FLIP SESSION \n");
#endif
InitIMark();
FlipSession=new vcg::LocalOptimization<BaseMesh>(base_mesh);
FlipSession=new vcg::LocalOptimization<BaseMesh>(base_mesh,&pecp);
FlipSession->Init<MyTriEdgeFlip>();
/*bool b=*/FlipSession->DoOptimization();
#ifndef _MESHLAB

View File

@ -956,7 +956,8 @@ void SmoothTexCoords(MESH_TYPE &m){
assert(m.HasPerVertexTexCoord());
typedef typename MESH_TYPE::VertexType::TexCoordType::PointType PointType;
typedef typename MESH_TYPE::VertexType::TexCoordType::ScalarType ScalarType;
SimpleTempData<typename MESH_TYPE::VertContainer, int> div(m.vert);
SimpleTempData<typename MESH_TYPE::VertContainer, PointType > sum(m.vert);