1 #ifndef _DIAMSAMPLER 2 #define _DIAMSAMPLER 3 #include <stat_remeshing.h> 4 #include <vcg/complex/algorithms/clean.h> 5 6 class DiamSampler{ 7 typedef IsoParametrization::CoordType CoordType; 8 typedef IsoParametrization::PScalarType PScalarType; 9 10 std::vector<std::vector<std::vector<CoordType> > > SampledPos; 11 IsoParametrization *isoParam; 12 unsigned int sampleSize; 13 DeAllocatePos()14 void DeAllocatePos() 15 { 16 ///positions 17 for (unsigned int i=0;i<SampledPos.size();i++) 18 { 19 for (unsigned int j=0;j<SampledPos[i].size();j++) 20 SampledPos[i][j].clear(); 21 SampledPos[i].clear(); 22 } 23 SampledPos.clear(); 24 } 25 AllocatePos(const int & sizeSampl)26 void AllocatePos(const int & sizeSampl) 27 { 28 ///positions 29 AbstractMesh *domain=isoParam->AbsMesh(); 30 int num_edges=0; 31 for (unsigned int i=0;i<domain->face.size();i++) 32 { 33 AbstractFace *f=&domain->face[i]; 34 for (int j=0;j<3;j++) 35 if (f->FFp(j)>f) 36 num_edges++; 37 } 38 39 SampledPos.resize(num_edges); 40 for (unsigned int i=0;i<SampledPos.size();i++) 41 { 42 SampledPos[i].resize(sizeSampl); 43 for (unsigned int j=0;j<SampledPos[i].size();j++) 44 SampledPos[i][j].resize(sizeSampl); 45 } 46 } 47 AveragePos(const std::vector<ParamFace * > & faces,std::vector<CoordType> & barys)48 CoordType AveragePos(const std::vector<ParamFace*> &faces, 49 std::vector<CoordType> &barys) 50 { 51 CoordType pos=CoordType(0,0,0); 52 for (unsigned int i=0;i<faces.size();i++) 53 { 54 pos+=(faces[i]->P(0)*barys[i].X()+ 55 faces[i]->P(1)*barys[i].Y()+ 56 faces[i]->P(2)*barys[i].Z()); 57 } 58 pos/=(PScalarType)faces.size(); 59 return pos; 60 } 61 62 int n_diamonds; 63 int inFace; 64 int inEdge; 65 int inStar; 66 int n_merged; 67 public: 68 69 ///initialize the sampler Init(IsoParametrization * _isoParam)70 void Init(IsoParametrization *_isoParam) 71 { 72 isoParam=_isoParam; 73 } 74 75 template <class OutputMesh> GetMesh(OutputMesh & SaveMesh)76 void GetMesh(OutputMesh &SaveMesh) 77 { 78 79 typedef typename OutputMesh::VertexType MyVertex; 80 81 SaveMesh.Clear(); 82 83 SaveMesh.vert.reserve(SampledPos.size()* 84 sampleSize* 85 sampleSize); 86 87 SaveMesh.face.reserve(SampledPos.size()* 88 (sampleSize-1)* 89 (sampleSize-1)*2); 90 91 SaveMesh.vn=0; 92 SaveMesh.fn=0; 93 94 ///supposed to be the same everywhere 95 ///allocate space 96 std::vector<std::vector<MyVertex*> > vertMatrix; 97 vertMatrix.resize(sampleSize); 98 for (unsigned int i=0;i<sampleSize;i++) 99 vertMatrix[i].resize(sampleSize); 100 101 ///add vertices 102 for (unsigned int i=0;i<SampledPos.size();i++) 103 //for (unsigned int i=11;i<12;i++) 104 { 105 ///add vertices & positions 106 for (unsigned int j=0;j<sampleSize;j++) 107 for (unsigned int k=0;k<sampleSize;k++) 108 { 109 vcg::tri::Allocator<OutputMesh>::AddVertex(SaveMesh,SampledPos[i][j][k]); 110 vertMatrix[j][k]=&SaveMesh.vert.back(); 111 } 112 /*printf("samppling %d\n",i);*/ 113 ///add faces 114 for (unsigned int j=0;j<sampleSize-1;j++) 115 for (unsigned int k=0;k<sampleSize-1;k++) 116 { 117 MyVertex *v0=vertMatrix[j][k]; 118 MyVertex *v1=vertMatrix[j+1][k]; 119 MyVertex *v2=vertMatrix[j+1][k+1]; 120 MyVertex *v3=vertMatrix[j][k+1]; 121 assert(vcg::tri::IsValidPointer(SaveMesh,v0)); 122 assert(vcg::tri::IsValidPointer(SaveMesh,v1)); 123 assert(vcg::tri::IsValidPointer(SaveMesh,v2)); 124 assert(vcg::tri::IsValidPointer(SaveMesh,v3)); 125 vcg::tri::Allocator<OutputMesh>::AddFace(SaveMesh,v0,v1,v3); 126 vcg::tri::Allocator<OutputMesh>::AddFace(SaveMesh,v1,v2,v3); 127 } 128 129 } 130 ///get minimum edge size 131 typename OutputMesh::ScalarType minE,maxE; 132 MaxMinEdge<OutputMesh>(SaveMesh,minE,maxE); 133 /*int num_tri=SampledPos.size()*sampleSize*sampleSize*2; 134 PScalarType Area_mesh=Area<OutputMesh>(SaveMesh); 135 PScalarType Edge=sqrt((((Area_mesh/(PScalarType)num_tri)*4.0)/(PScalarType)sqrt(3.0)));*/ 136 n_merged=vcg::tri::Clean<OutputMesh>::MergeCloseVertex(SaveMesh,(PScalarType)minE*(PScalarType)0.9); 137 vcg::tri::UpdateNormal<OutputMesh>::PerVertexNormalized(SaveMesh); 138 /*Log("Merged %d vertices\n",merged);*/ 139 } 140 141 //typedef enum SampleAttr{SMNormal, SMColor, SMPosition}; 142 143 ///sample the parametrization SamplePos(const int & size)144 bool SamplePos(const int &size) 145 { 146 if (size<2) 147 return false; 148 sampleSize=size; 149 DeAllocatePos();//clear old data 150 AllocatePos(size); ///allocate for new one 151 inFace=0; 152 inEdge=0; 153 inStar=0; 154 int global=0; 155 156 ///start sampling values 157 /*Log("Num Diamonds: %d \n",SampledPos.size());*/ 158 159 160 for (unsigned int diam=0;diam<SampledPos.size();diam++) 161 for (unsigned int j=0;j<sampleSize;j++) 162 for (unsigned int k=0;k<sampleSize;k++) 163 { 164 vcg::Point2<PScalarType> UVQuad,UV; 165 UVQuad.X()=(PScalarType)j/(PScalarType)(sampleSize-1); 166 UVQuad.Y()=(PScalarType)k/(PScalarType)(sampleSize-1); 167 int I; 168 //printf("Quad: %d,%f,%f \n",diam,UV.X(),UV.Y()); 169 ///get coordinate in parametric space 170 isoParam->inv_GE1Quad(diam,UVQuad,I,UV); 171 //printf("Alfabeta: %d,%f,%f \n",I,UV.X(),UV.Y()); 172 ///and sample 173 std::vector<ParamFace*> faces; 174 std::vector<CoordType> barys; 175 int domain=isoParam->Theta(I,UV,faces,barys); 176 177 if (domain==0) 178 inFace++; 179 else 180 if (domain==1) 181 inEdge++; 182 else 183 if (domain==2) 184 inStar++; 185 186 global++; 187 //printf("Find in domain: %d \n",domain); 188 ///store value 189 CoordType val=AveragePos(faces,barys); 190 /*if (domain==2) 191 val=CoordType(0,0,0);*/ 192 SampledPos[diam][j][k]=val; 193 } 194 return true; 195 /*#ifndef _MESHLAB 196 printf("In Face: %f \n",(PScalarType)inFace/(PScalarType)global); 197 printf("In Diamond: %f \n",(PScalarType)inEdge/(PScalarType)global); 198 printf("In Star: %f \n",(PScalarType)inStar/(PScalarType)global); 199 #endif*/ 200 /*Log("In Face: %f \n",(PScalarType)inFace/(PScalarType)global); 201 Log("In Diamond: %f \n",(PScalarType)inEdge/(PScalarType)global); 202 Log("In Star: %f \n",(PScalarType)inStar/(PScalarType)global);*/ 203 } 204 getResData(int & _n_diamonds,int & _inFace,int & _inEdge,int & _inStar,int & _n_merged)205 void getResData(int &_n_diamonds,int &_inFace, 206 int &_inEdge,int &_inStar,int &_n_merged) 207 { 208 _n_diamonds=n_diamonds; 209 _inFace=inFace; 210 _inEdge=inEdge; 211 _inStar=inStar; 212 _n_merged=n_merged; 213 } 214 GetCoords(std::vector<CoordType> & positions)215 void GetCoords(std::vector<CoordType> &positions) 216 { 217 for (unsigned int diam=0;diam<SampledPos.size();diam++) 218 for (unsigned int j=0;j<sampleSize;j++) 219 for (unsigned int k=0;k<sampleSize;k++) 220 positions.push_back(SampledPos[diam][j][k]); 221 } 222 223 224 }; 225 #endif 226