File: picking.h

package info (click to toggle)
meshlab 2020.09%2Bdfsg1-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 45,124 kB
  • sloc: cpp: 400,238; ansic: 31,952; javascript: 1,578; sh: 387; yacc: 238; lex: 139; python: 86; makefile: 29
file content (158 lines) | stat: -rw-r--r-- 5,681 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#pragma once
/****************************************************************************
* VCGLib                                                            o o     *
* Visual and Computer Graphics Library                            o     o   *
*                                                                _   O  _   *
* Copyright(C) 2004-2016                                           \/)\/    *
* Visual Computing Lab                                            /\/|      *
* ISTI - Italian National Research Council                           |      *
*                                                                    \      *
* All rights reserved.                                                      *
*                                                                           *
* This program is free software; you can redistribute it and/or modify      *
* it under the terms of the GNU General Public License as published by      *
* the Free Software Foundation; either version 2 of the License, or         *
* (at your option) any later version.                                       *
*                                                                           *
* This program is distributed in the hope that it will be useful,           *
* but WITHOUT ANY WARRANTY; without even the implied warranty of            *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt)          *
* for more details.                                                         *
*                                                                           *
****************************************************************************/
/****************************************************************************
This file contains two function providing the standard way to do picking using opendgl:
- using the SELECT mode (first function)
- using the depth buffer and gluUnproject (second function)

  History
$Log: not supported by cvs2svn $
Revision 1.5  2007/05/21 13:22:40  cignoni
Corrected gcc compiling issues

Revision 1.4  2006/10/27 08:55:15  fiorin
Added type cast (in order to remove warnings)

Revision 1.3  2006/02/28 13:25:48  ponchio
for(ii... -> for(int ii

Revision 1.2  2006/02/13 13:06:34  cignoni
Removed glut. Added ifdef guards and namespace.
Added bool return value to the pick function

Revision 1.1  2005/12/03 09:36:28  ganovelli
*** empty log message ***

****************************************************************************/

#ifndef WRAP_GL_PICKING_H
#define WRAP_GL_PICKING_H

#include <algorithm>

#ifndef GLU_VERSIONS
#ifdef __APPLE__
#include <OpenGL/glu.h>
#else
#ifdef _WIN32
  #include <windows.h>
#endif
#include <GL/glu.h>
#endif
#endif

namespace vcg
{

template <class TO_PICK_CONT_TYPE>
int Pick(	const int & x, const int &y,
                    TO_PICK_CONT_TYPE &m,
                    std::vector<typename TO_PICK_CONT_TYPE::value_type*> &result,
                    void (draw_func)(typename TO_PICK_CONT_TYPE::value_type &),
                    int width=4,
                    int height=4)
    {
        result.clear();
        long hits;
        int sz = int(m.size())*5;
        GLuint *selectBuf =new GLuint[sz];
        glSelectBuffer(sz, selectBuf);
        glRenderMode(GL_SELECT);
        glInitNames();

        /* Because LoadName() won't work with no names on the stack */
        glPushName(-1);
        double mp[16];

        GLint viewport[4];
        glGetIntegerv(GL_VIEWPORT,viewport);
        glPushAttrib(GL_TRANSFORM_BIT);
        glMatrixMode(GL_PROJECTION);
        glGetDoublev(GL_PROJECTION_MATRIX ,mp);
        glPushMatrix();
        glLoadIdentity();
        //gluPickMatrix(x, viewport[3]-y, 4, 4, viewport);
        gluPickMatrix(x, y, width, height, viewport);
        glMultMatrixd(mp);

        glMatrixMode(GL_MODELVIEW);
        glPushMatrix();
        int cnt=0;
        typename TO_PICK_CONT_TYPE::iterator  ei;
        for(ei=m.begin();ei!=m.end();++ei)
        {

                glLoadName(cnt);
                draw_func(*ei);
                cnt++;
        }

        glPopMatrix();
        glMatrixMode(GL_PROJECTION);
        glPopMatrix();
        glMatrixMode(GL_MODELVIEW);
        hits = glRenderMode(GL_RENDER);

        if (hits <= 0)     return 0;
        std::vector< std::pair<double,unsigned int> > H;
        for(int ii=0;ii<hits;ii++){
            H.push_back( std::pair<double,unsigned int>(selectBuf[ii*4+1]/4294967295.0,selectBuf[ii*4+3]));
        }
        std::sort(H.begin(),H.end());

        result.resize(H.size());
        for(int ii=0;ii<hits;ii++){
            typename TO_PICK_CONT_TYPE::iterator ei=m.begin();
            std::advance(ei ,H[ii].second);
            result[ii]=&*ei;
        }
        glPopAttrib();
        delete [] selectBuf;
        return int(result.size());
    }

// 10/2/06 Slightly changed the interface.
// Return value is used to determine if the picked point was against the far plane
// (and therefore nothing was picked)
template <class PointType>
bool Pick(const int & x, const int &y, PointType &pp){
    GLdouble res[3];
    GLdouble mm[16],pm[16]; GLint vp[4];
    glGetDoublev(GL_MODELVIEW_MATRIX,mm);
    glGetDoublev(GL_PROJECTION_MATRIX,pm);
    glGetIntegerv(GL_VIEWPORT,vp);

    GLfloat   pix;
    glReadPixels(x,y,1,1,GL_DEPTH_COMPONENT,GL_FLOAT,&pix);
  GLfloat depthrange[2]={0,0};
  glGetFloatv(GL_DEPTH_RANGE,depthrange);
  if(pix==depthrange[1]) return false;
    gluUnProject(x,y,pix,mm,pm,vp,&res[0],&res[1],&res[2]);
    pp=PointType (res[0],res[1],res[2]);
  return true;
    }

} // end namespace

#endif