00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef __PICK______H
00034 #define __PICK______H
00035
00036 #include <vector>
00037 #include <algorithm>
00038 namespace vcg{
00039
00040 template <class MESH_TYPE>
00041 class GLPickTri
00042 {
00043 typedef typename MESH_TYPE::FaceIterator FaceIterator;
00044 typedef typename MESH_TYPE::VertexIterator VertexIterator;
00045 typedef typename MESH_TYPE::FacePointer FacePointer;
00046 typedef typename MESH_TYPE::VertexPointer VertexPointer;
00047 typedef typename MESH_TYPE::VertexType VertexType;
00048
00049 public:
00050
00051 static bool PickNearestFace(int x, int y, MESH_TYPE &m, FacePointer &fi,int width=4, int height=4)
00052 {
00053 std::vector<FacePointer> result;
00054 int val=PickFace(x,y,m,result,width,height);
00055 if(val!=0)
00056 {
00057 fi=result[0];
00058 return true;
00059 }
00060 fi=NULL;
00061 return false;
00062 }
00063 static int PickVert(int x, int y, MESH_TYPE &m, std::vector<VertexPointer> &result, int width=4, int height=4,bool sorted=true)
00064 {
00065 result.clear();
00066 if(width==0 ||height==0) return 0;
00067 long hits;
00068 int sz=m.vert.size()*5;
00069 GLuint *selectBuf =new GLuint[sz];
00070 glSelectBuffer(sz, selectBuf);
00071 glRenderMode(GL_SELECT);
00072 glInitNames();
00073
00074
00075 glPushName(-1);
00076 double mp[16];
00077
00078 GLint viewport[4];
00079 glGetIntegerv(GL_VIEWPORT,viewport);
00080 glMatrixMode(GL_PROJECTION);
00081 glGetDoublev(GL_PROJECTION_MATRIX ,mp);
00082 glPushMatrix();
00083 glLoadIdentity();
00084 gluPickMatrix(x, y, width, height, viewport);
00085 glMultMatrixd(mp);
00086
00087 glMatrixMode(GL_MODELVIEW);
00088 glPushMatrix();
00089 int vcnt=0;
00090 VertexIterator vi;
00091 for(vi=m.vert.begin();vi!=m.vert.end();++vi)
00092 {
00093 if(!(*vi).IsD())
00094 {
00095 glLoadName(vcnt);
00096 glBegin(GL_POINTS);
00097 glVertex( (*vi).P() );
00098 glEnd();
00099 }
00100 vcnt++;
00101 }
00102
00103 glPopMatrix();
00104 glMatrixMode(GL_PROJECTION);
00105 glPopMatrix();
00106 glMatrixMode(GL_MODELVIEW);
00107 hits = glRenderMode(GL_RENDER);
00108 std::vector< std::pair<double,unsigned int> > H;
00109 for(long ii=0;ii<hits;ii++){
00110 H.push_back( std::pair<double,unsigned int>(selectBuf[ii*4+1]/4294967295.0,selectBuf[ii*4+3]));
00111 }
00112 if(sorted)
00113 std::sort(H.begin(),H.end());
00114 result.resize(H.size());
00115 for(long ii=0;ii<hits;ii++){
00116 VertexIterator vi=m.vert.begin();
00117 advance(vi ,H[ii].second);
00118 result[ii]=&*vi;
00119 }
00120
00121 delete [] selectBuf;
00122 return result.size();
00123 }
00124
00125 static int PickFace(int x, int y, MESH_TYPE &m, std::vector<FacePointer> &result, int width=4, int height=4,bool sorted=true)
00126 {
00127 result.clear();
00128 if(width==0 ||height==0) return 0;
00129 long hits;
00130 int sz=m.face.size()*5;
00131 GLuint *selectBuf =new GLuint[sz];
00132
00133 glSelectBuffer(sz, selectBuf);
00134 glRenderMode(GL_SELECT);
00135 glInitNames();
00136
00137
00138 glPushName(-1);
00139 double mp[16];
00140
00141 GLint viewport[4];
00142 glGetIntegerv(GL_VIEWPORT,viewport);
00143 glMatrixMode(GL_PROJECTION);
00144 glGetDoublev(GL_PROJECTION_MATRIX ,mp);
00145 glPushMatrix();
00146 glLoadIdentity();
00147
00148 gluPickMatrix(x, y, width, height, viewport);
00149 glMultMatrixd(mp);
00150
00151 glMatrixMode(GL_MODELVIEW);
00152 glPushMatrix();
00153 int fcnt=0;
00154 FaceIterator fi;
00155 for(fi=m.face.begin();fi!=m.face.end();++fi)
00156 {
00157 if(!(*fi).IsD())
00158 {
00159 glLoadName(fcnt);
00160 glBegin(GL_TRIANGLES);
00161 glVertex( (*fi).V(0)->P() );
00162 glVertex( (*fi).V(1)->P() );
00163 glVertex( (*fi).V(2)->P() );
00164 glEnd();
00165 }
00166 fcnt++;
00167 }
00168
00169 glPopMatrix();
00170 glMatrixMode(GL_PROJECTION);
00171 glPopMatrix();
00172 glMatrixMode(GL_MODELVIEW);
00173 hits = glRenderMode(GL_RENDER);
00174
00175
00176 std::vector< std::pair<double,unsigned int> > H;
00177 for(long ii=0;ii<hits;ii++){
00178
00179 H.push_back( std::pair<double,unsigned int>(selectBuf[ii*4+1]/4294967295.0,selectBuf[ii*4+3]));
00180 }
00181 if(sorted)
00182 std::sort(H.begin(),H.end());
00183
00184 result.resize(H.size());
00185 for(long ii=0;ii<hits;ii++){
00186 FaceIterator fi=m.face.begin();
00187 advance(fi ,H[ii].second);
00188 result[ii]=&*fi;
00189 }
00190
00191 delete [] selectBuf;
00192 return result.size();
00193 }
00194
00195
00196
00197 static int PickFaceVisible(int x, int y, MESH_TYPE &m, std::vector<FacePointer> &resultZ, int width=4, int height=4, bool sorted=true)
00198 {
00199
00200
00201 double mm[16];
00202 double mp[16];
00203 GLint vp[4];
00204 glGetIntegerv(GL_VIEWPORT,vp);
00205 glGetDoublev(GL_MODELVIEW_MATRIX ,mm);
00206 glGetDoublev(GL_PROJECTION_MATRIX ,mp);
00207 int screenW = vp[2]-vp[0];
00208 int screenH = vp[3]-vp[1];
00209
00210 GLfloat *buffer = new GLfloat[screenW*screenH];
00211 glReadPixels(vp[0],vp[1],vp[2],vp[3],GL_DEPTH_COMPONENT,GL_FLOAT,buffer);
00212
00213 std::vector<FacePointer> result;
00214 PickFace(x,y,m,result,width,height,sorted);
00215 float LocalEpsilon = 0.001f;
00216 for(size_t i =0;i<result.size();++i)
00217 {
00218 typename VertexType::CoordType v=Barycenter(*(result[i]));
00219 GLdouble tx,ty,tz;
00220 gluProject(v.X(),v.Y(),v.Z(), mm,mp,vp, &tx,&ty,&tz);
00221 if(tx >=0 && tx<screenW && ty >=0 && ty<screenH)
00222 {
00223 float bufZ = buffer[int(tx)+int(ty)*screenW];
00224
00225 if(bufZ + LocalEpsilon >= tz)
00226 resultZ.push_back(result[i]);
00227 }
00228 }
00229
00230 delete [] buffer;
00231 return resultZ.size();
00232 }
00233
00234 };
00235
00236
00238 template <class TETRA_MESH_TYPE>
00239 class GLPickTetra
00240 {
00241 typedef typename TETRA_MESH_TYPE::TetraIterator TetraIterator;
00242 typedef typename TETRA_MESH_TYPE::TetraPointer TetraPointer;
00243 typedef typename TETRA_MESH_TYPE::VertexType VertexType;
00244
00245 public:
00246 static bool PickNearestTetra(int x, int y,TETRA_MESH_TYPE &m, TetraIterator &ti,int width=4, int height=4)
00247 {
00248 std::vector<TetraPointer> result;
00249 int val=PickTetra(x,y,m,result,width,height);
00250 if(val!=0)
00251 {
00252 ti=result[0];
00253 return true;
00254 }
00255 ti=0;
00256 return false;
00257 }
00258
00259
00260
00261 class Tetra;
00262
00263 static int PickTetra(int x, int y, TETRA_MESH_TYPE &m, std::vector<TetraPointer> &result, int width=4, int height=4)
00264 {
00265 result.clear();
00266 long hits;
00267 int sz=m.tetra.size()*5;
00268 unsigned int *selectBuf =new unsigned int[sz];
00269
00270 glSelectBuffer(sz, selectBuf);
00271 glRenderMode(GL_SELECT);
00272 glInitNames();
00273
00274
00275 glPushName(-1);
00276 double mp[16];
00277
00278 int viewport[4];
00279 glGetIntegerv(GL_VIEWPORT,viewport);
00280 glMatrixMode(GL_PROJECTION);
00281 glGetDoublev(GL_PROJECTION_MATRIX ,mp);
00282 glPushMatrix();
00283 glLoadIdentity();
00284
00285 gluPickMatrix(x, y, width, height, viewport);
00286 glMultMatrixd(mp);
00287
00288 glMatrixMode(GL_MODELVIEW);
00289 glPushMatrix();
00290 int tetracnt=0;
00291 TetraIterator ti;
00292 for(ti=m.tetra.begin();ti!=m.tetra.end();++ti)
00293 {
00294 if(!(*ti).IsD())
00295 {
00296 glLoadName(tetracnt);
00297 glBegin(GL_TRIANGLES);
00298 for (int face=0;face<4;face++)
00299 {
00300
00301 VertexType *v0=ti->V(Tetra::VofF(face,0));
00302 VertexType *v1=ti->V(Tetra::VofF(face,1));
00303 VertexType *v2=ti->V(Tetra::VofF(face,2));
00304 glVertex(v0->P());
00305 glVertex(v1->P());
00306 glVertex(v2->P());
00307
00308 }
00309 glEnd();
00310 tetracnt++;
00311 }
00312
00313 }
00314
00315 glPopMatrix();
00316 glMatrixMode(GL_PROJECTION);
00317 glPopMatrix();
00318 glMatrixMode(GL_MODELVIEW);
00319 hits = glRenderMode(GL_RENDER);
00320
00321
00322 std::vector< std::pair<double,unsigned int> > H;
00323 int ii;
00324 for(ii=0;ii<hits;ii++){
00325
00326 H.push_back( std::pair<double,unsigned int>(selectBuf[ii*4+1]/4294967295.0,selectBuf[ii*4+3]));
00327 }
00328 std::sort(H.begin(),H.end());
00329
00330 result.resize(H.size());
00331 for(ii=0;ii<hits;ii++){
00332 TetraIterator ti=m.tetra.begin();
00333 advance(ti ,H[ii].second);
00334 result[ii]=&*ti;
00335 }
00336
00337 delete [] selectBuf;
00338 return result.size();
00339 }
00340
00341 static bool PickNearestTetraFace(int x, int y,TETRA_MESH_TYPE &m, TetraIterator &ti,int &face,int width=4, int height=4)
00342 {
00343 std::vector<std::pair<TetraPointer,int> > result;
00344 int val=PickTetraFace(x,y,m,result,width,height);
00345 if(val!=0)
00346 {
00347 ti=result[0].first;
00348 face=result[0].second;
00349 return true;
00350 }
00351 ti=0;
00352 face=-1;
00353 return false;
00354 }
00355
00356 static int PickTetraFace(int x, int y, TETRA_MESH_TYPE &m, std::vector<std::pair<TetraPointer,int> > &result, int width=4, int height=4)
00357 {
00358 result.clear();
00359 long hits;
00360 int sz=(m.tetra.size()*4)*5;
00361 unsigned int *selectBuf =new unsigned int[sz];
00362
00363 glSelectBuffer(sz, selectBuf);
00364 glRenderMode(GL_SELECT);
00365 glInitNames();
00366
00367
00368 glPushName(-1);
00369 double mp[16];
00370
00371 int viewport[4];
00372 glGetIntegerv(GL_VIEWPORT,viewport);
00373 glMatrixMode(GL_PROJECTION);
00374 glGetDoublev(GL_PROJECTION_MATRIX ,mp);
00375 glPushMatrix();
00376 glLoadIdentity();
00377
00378 gluPickMatrix(x, y, width, height, viewport);
00379 glMultMatrixd(mp);
00380 glMatrixMode(GL_MODELVIEW);
00381 glPushMatrix();
00382 int tetracnt=0;
00383 TetraIterator ti;
00384 VertexType *v0;
00385 VertexType *v1;
00386 VertexType *v2;
00387 int face;
00388 for(ti=m.tetra.begin();ti!=m.tetra.end();++ti)
00389 {
00390 if(!(*ti).IsD())
00391 {
00392 for (face=0;face<4;face++){
00393 v0=ti->V(Tetra::VofF(face,0));
00394 v1=ti->V(Tetra::VofF(face,1));
00395 v2=ti->V(Tetra::VofF(face,2));
00396 glLoadName(tetracnt);
00397 glBegin(GL_TRIANGLES);
00398 glVertex(v0->P());
00399 glVertex(v1->P());
00400 glVertex(v2->P());
00401 glEnd();
00402 tetracnt++;
00403 }
00404 }
00405 }
00406
00407 glPopMatrix();
00408 glMatrixMode(GL_PROJECTION);
00409 glPopMatrix();
00410 glMatrixMode(GL_MODELVIEW);
00411 hits = glRenderMode(GL_RENDER);
00412
00413
00414 std::vector< std::pair<double,unsigned int> > H;
00415 int ii;
00416 for(ii=0;ii<hits;ii++){
00417
00418 H.push_back( std::pair<double,unsigned int>(selectBuf[ii*4+1]/4294967295.0,selectBuf[ii*4+3]));
00419 }
00420 std::sort(H.begin(),H.end());
00421
00422 result.resize(H.size());
00423 for(ii=0;ii<hits;ii++){
00424 TetraIterator ti=m.tetra.begin();
00425 int index=H[ii].second;
00426 advance(ti ,(int)(index/4));
00427 result[ii]=std::pair<TetraPointer,int>(&*ti,index%4);
00428 }
00429
00430 delete [] selectBuf;
00431 return result.size();
00432 }
00433
00434 };
00435
00436
00437 }
00438
00439 #endif