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