diff --git a/vcg/complex/algorithms/curve_on_manifold.h b/vcg/complex/algorithms/curve_on_manifold.h index 2c8e4abe..e03e1f5f 100644 --- a/vcg/complex/algorithms/curve_on_manifold.h +++ b/vcg/complex/algorithms/curve_on_manifold.h @@ -1141,7 +1141,7 @@ public: } }; -struct EdgePointSplit : public std::unary_function , CoordType> +struct EdgePointSplit { public: std::map, VertexPointer> &edgeToPolyVertMap; diff --git a/wrap/gl/pick.h b/wrap/gl/pick.h index 33461bb5..4d327d14 100644 --- a/wrap/gl/pick.h +++ b/wrap/gl/pick.h @@ -24,403 +24,220 @@ #ifndef __PICK______H #define __PICK______H +// Assumes OpenGL already included + #include #include #include - namespace vcg{ template class GLPickTri { - typedef typename MESH_TYPE::ScalarType ScalarType; - typedef typename MESH_TYPE::CoordType CoordType; - typedef typename MESH_TYPE::FaceIterator FaceIterator; - typedef typename MESH_TYPE::VertexIterator VertexIterator; - typedef typename MESH_TYPE::FacePointer FacePointer; - typedef typename MESH_TYPE::VertexPointer VertexPointer; - typedef typename MESH_TYPE::VertexType VertexType; - public: - static CoordType glProject(const Eigen::Matrix &M, const ScalarType * viewport, const CoordType &p) - { - const ScalarType vx=viewport[0]; - const ScalarType vy=viewport[1]; - const ScalarType vw2=viewport[2]/ScalarType(2.0); - const ScalarType vh2=viewport[3]/ScalarType(2.0); - Eigen::Matrix vp(p[0],p[1],p[2],ScalarType(1.0)); - Eigen::Matrix vpp = M*vp; - Eigen::Matrix ndc = vpp/vpp[3]; + typedef typename MESH_TYPE::ScalarType ScalarType; + typedef typename MESH_TYPE::CoordType CoordType; + typedef typename MESH_TYPE::FaceIterator FaceIterator; + typedef typename MESH_TYPE::VertexIterator VertexIterator; + typedef typename MESH_TYPE::FacePointer FacePointer; + typedef typename MESH_TYPE::VertexPointer VertexPointer; + typedef typename MESH_TYPE::VertexType VertexType; - CoordType sc( - vw2*ndc[0] + vx+vw2, - vh2*ndc[1] + vy+vh2, - ndc[2] - ); + static CoordType glProject(const Eigen::Matrix &M, const ScalarType * viewport, const CoordType &p) + { + const ScalarType vx=viewport[0]; + const ScalarType vy=viewport[1]; + const ScalarType vw2=viewport[2]/ScalarType(2.0); + const ScalarType vh2=viewport[3]/ScalarType(2.0); + Eigen::Matrix vp(p[0],p[1],p[2],ScalarType(1.0)); + Eigen::Matrix vpp = M*vp; + Eigen::Matrix ndc = vpp/vpp[3]; - return sc; - } + CoordType sc(vw2*ndc[0] + vx+vw2, + vh2*ndc[1] + vy+vh2, + ndc[2]); - static void FillProjectedVector(MESH_TYPE &m, std::vector &pVec, const Eigen::Matrix &M, const ScalarType * viewportF) - { - pVec.resize(m.vert.size()); - for(size_t i=0;i::glProject(M, viewportF,CoordType::Construct(m.vert[i].P())); - } - } + return sc; + } - static void glGetMatrixAndViewport(Eigen::Matrix &M, ScalarType *viewportF) - { - Eigen::Matrix4d mp,mm; + static void FillProjectedVector(MESH_TYPE &m, std::vector &pVec, const Eigen::Matrix &M, const ScalarType * viewportF) + { + pVec.resize(m.vert.size()); + for(size_t i=0;i::glProject(M, viewportF,CoordType::Construct(m.vert[i].P())); + } + } - GLint viewport[4]; - glGetIntegerv(GL_VIEWPORT,viewport); - for(int i=0;i<4;++i) viewportF[i]=viewport[i]; + static void glGetMatrixAndViewport(Eigen::Matrix &M, ScalarType *viewportF) + { + Eigen::Matrix4d mp,mm; - glGetDoublev(GL_PROJECTION_MATRIX, mp.data()); - glGetDoublev(GL_MODELVIEW_MATRIX, mm.data()); + GLint viewport[4]; + glGetIntegerv(GL_VIEWPORT,viewport); + for(int i=0;i<4;++i) viewportF[i]=viewport[i]; - M = (mp*mm).cast(); - } + glGetDoublev(GL_PROJECTION_MATRIX, mp.data()); + glGetDoublev(GL_MODELVIEW_MATRIX, mm.data()); - // compute a bbox in Device Coordinate (with the z without the near far normalization and ranged in -1 1) - static Box3 ComputeDCBox(int x, int y, int width, int height) - { - Box3 bb; - bb.SetNull(); - bb.Add(CoordType(x-width/ScalarType(2.0),y-height/ScalarType(2.0),ScalarType(-1.0))); - bb.Add(CoordType(x+width/ScalarType(2.0),y+height/ScalarType(2.0), ScalarType(1.0))); - return bb; - } + M = (mp*mm).cast(); + } -public: + // compute a bbox in Device Coordinate (with the z without the near far normalization and ranged in -1 1) + static Box3 ComputeDCBox(int x, int y, int width, int height) + { + Box3 bb; + bb.SetNull(); + bb.Add(CoordType(x-width/ScalarType(2.0),y-height/ScalarType(2.0),ScalarType(-1.0))); + bb.Add(CoordType(x+width/ScalarType(2.0),y+height/ScalarType(2.0), ScalarType(1.0))); + return bb; + } - static bool PickClosestFace(int x, int y, MESH_TYPE &m, FacePointer &fp,int width=4, int height=4) - { - Eigen::Matrix M; - ScalarType viewportF[4]; - glGetMatrixAndViewport(M,viewportF); - Box3 reg=ComputeDCBox(x,y,width,height); + static bool PickClosestFace(int x, int y, MESH_TYPE &m, FacePointer &fp,int width=4, int height=4) + { + Eigen::Matrix M; + ScalarType viewportF[4]; + glGetMatrixAndViewport(M,viewportF); + Box3 reg=ComputeDCBox(x,y,width,height); - ScalarType bzmin = std::numeric_limits::max(); - fp=0; - for(size_t i=0;i::max(); + fp=0; + for(size_t i=0;i M; - ScalarType viewportF[4]; - glGetMatrixAndViewport(M,viewportF); - ScalarType bzmin = std::numeric_limits::max(); - vp=0; + static bool PickClosestVert(int x, int y, MESH_TYPE &m, VertexPointer &vp,int width=4, int height=4) + { + Eigen::Matrix M; + ScalarType viewportF[4]; + glGetMatrixAndViewport(M,viewportF); + ScalarType bzmin = std::numeric_limits::max(); + vp=0; - Box3 reg=ComputeDCBox(x,y,width,height); + Box3 reg=ComputeDCBox(x,y,width,height); - for(size_t i=0;i &result, int width=4, int height=4) - { - result.clear(); - static Eigen::Matrix lastM; - static MESH_TYPE *lastm=0; - static std::vector pVec; + static int PickVert(int x, int y, MESH_TYPE &m, std::vector &result, int width=4, int height=4) + { + result.clear(); + static Eigen::Matrix lastM; + static MESH_TYPE *lastm=0; + static std::vector pVec; - Eigen::Matrix M; - ScalarType viewportF[4]; - glGetMatrixAndViewport(M,viewportF); + Eigen::Matrix M; + ScalarType viewportF[4]; + glGetMatrixAndViewport(M,viewportF); - Box3 reg =ComputeDCBox(x,y,width,height); + Box3 reg =ComputeDCBox(x,y,width,height); - if ((M != lastM) || (&m != lastm) || (pVec.size() != m.VN())) - { - FillProjectedVector(m,pVec,M,viewportF); - lastM = M; - lastm = &m; - } + if ((M != lastM) || (&m != lastm) || (pVec.size() != m.VN())) + { + FillProjectedVector(m,pVec,M,viewportF); + lastM = M; + lastm = &m; + } - for(size_t i=0;i &result, int width = 4, int height = 4) - { - static Eigen::Matrix lastM; - static MESH_TYPE *lastm = 0; - static std::vector pVec; + static int PickFace(int x, int y, MESH_TYPE &m, std::vector &result, int width = 4, int height = 4) + { + static Eigen::Matrix lastM; + static MESH_TYPE *lastm = 0; + static std::vector pVec; - ScalarType viewportF[4]; - Eigen::Matrix M; - glGetMatrixAndViewport(M, viewportF); - result.clear(); - Box3 reg; - reg.Add(CoordType(x - width / ScalarType(2.0), y - height / ScalarType(2.0), ScalarType(-1.0))); - reg.Add(CoordType(x + width / ScalarType(2.0), y + height / ScalarType(2.0), ScalarType(1.0))); + ScalarType viewportF[4]; + Eigen::Matrix M; + glGetMatrixAndViewport(M, viewportF); + result.clear(); + Box3 reg; + reg.Add(CoordType(x - width / ScalarType(2.0), y - height / ScalarType(2.0), ScalarType(-1.0))); + reg.Add(CoordType(x + width / ScalarType(2.0), y + height / ScalarType(2.0), ScalarType(1.0))); - - if ((M != lastM) || (&m != lastm) || (pVec.size() != m.VN())) - { - FillProjectedVector(m, pVec, M, viewportF); - lastM = M; - lastm = &m; - } + if ((M != lastM) || (&m != lastm) || (pVec.size() != m.VN())) + { + FillProjectedVector(m, pVec, M, viewportF); + lastM = M; + lastm = &m; + } - for (size_t i = 0; i < m.face.size(); ++i) - { - if (!m.face[i].IsD()) - { - const CoordType &p0 = pVec[tri::Index(m, m.face[i].V(0))]; - const CoordType &p1 = pVec[tri::Index(m, m.face[i].V(1))]; - const CoordType &p2 = pVec[tri::Index(m, m.face[i].V(2))]; + for (size_t i = 0; i < m.face.size(); ++i) + { + if (!m.face[i].IsD()) + { + const CoordType &p0 = pVec[tri::Index(m, m.face[i].V(0))]; + const CoordType &p1 = pVec[tri::Index(m, m.face[i].V(1))]; + const CoordType &p2 = pVec[tri::Index(m, m.face[i].V(2))]; - if (!(abs(p0[2]) > 1 || abs(p1[2]) > 1 || abs(p2[2]) > 1) && IntersectionTriangleBox(reg, p0, p1, p2)) - result.push_back(&m.face[i]); - } - } - return result.size(); - } + if (!(abs(p0[2]) > 1 || abs(p1[2]) > 1 || abs(p2[2]) > 1) && IntersectionTriangleBox(reg, p0, p1, p2)) + result.push_back(&m.face[i]); + } + } + return result.size(); + } - // Same of above but it also assumes that you want only visible faces. - // Visibility is computed according to the current depth buffer. - static int PickVisibleFace(int x, int y, MESH_TYPE &m, std::vector &resultZ, int width=4, int height=4) - { - ScalarType vp[4]; - Eigen::Matrix M; - glGetMatrixAndViewport(M,vp); + // Same of above but it also assumes that you want only visible faces. + // Visibility is computed according to the current depth buffer. + static int PickVisibleFace(int x, int y, MESH_TYPE &m, std::vector &resultZ, int width=4, int height=4) + { + ScalarType vp[4]; + Eigen::Matrix M; + glGetMatrixAndViewport(M,vp); - int screenW = (int)(vp[2]-vp[0]); - int screenH = (int)(vp[3]-vp[1]); + int screenW = (int)(vp[2]-vp[0]); + int screenH = (int)(vp[3]-vp[1]); - GLfloat *buffer = new GLfloat[screenW*screenH]; + GLfloat *buffer = new GLfloat[screenW*screenH]; - //glReadPixels does NOT accept GL_DOUBLE - //GLenum err = glGetError(); - glReadPixels(vp[0],vp[1],vp[2],vp[3],GL_DEPTH_COMPONENT,GL_FLOAT,buffer); - //err = glGetError(); - std::vector result; - PickFace(x,y,m,result,width,height); - ScalarType LocalEpsilon(ScalarType(0.001)); - for(size_t i =0;i=0 && p[0]=0 && p[1]= ScalarType(p[2]+1.0)/2.0) - resultZ.push_back(result[i]); - } - } + //glReadPixels does NOT accept GL_DOUBLE + //GLenum err = glGetError(); + glReadPixels(vp[0],vp[1],vp[2],vp[3],GL_DEPTH_COMPONENT,GL_FLOAT,buffer); + //err = glGetError(); + std::vector result; + PickFace(x,y,m,result,width,height); + ScalarType LocalEpsilon(ScalarType(0.001)); + for(size_t i =0;i=0 && p[0]=0 && p[1]= ScalarType(p[2]+1.0)/2.0) + resultZ.push_back(result[i]); + } + } - delete [] buffer; - return resultZ.size(); - } - - -#ifdef _I_REALLY_NEED_OLD_GL_PICK_ - // Same of above but it also assumes that you want only visible faces. - // Visibility is computed according to the current depth buffer. - static int OldPickFaceVisible(int x, int y, MESH_TYPE &m, std::vector &resultZ, int width=4, int height=4, bool sorted=true) - { - // First step - - double mm[16]; - double mp[16]; - GLint vp[4]; - glGetIntegerv(GL_VIEWPORT,vp); - glGetDoublev(GL_MODELVIEW_MATRIX ,mm); - glGetDoublev(GL_PROJECTION_MATRIX ,mp); - int screenW = vp[2]-vp[0]; - int screenH = vp[3]-vp[1]; - - - GLfloat *buffer = new GLfloat[screenW*screenH]; - - //GLenum err = glGetError(); - glReadPixels(vp[0],vp[1],vp[2],vp[3],GL_DEPTH_COMPONENT,GL_FLOAT,buffer); - //err = glGetError(); - - std::vector result; - OldPickFace(x,y,m,result,width,height,sorted); - ScalarType LocalEpsilon(0.001); - for(size_t i =0;i=0 && tx=0 && ty= tz) - resultZ.push_back(result[i]); - } - } - - delete [] buffer; - return resultZ.size(); - } - - static int OldPickFace(int x, int y, MESH_TYPE &m, std::vector &result, int width=4, int height=4,bool sorted=true) - { - result.clear(); - if(width==0 ||height==0) return 0; - long hits; - int sz=m.face.size()*5; - GLuint *selectBuf =new GLuint[sz]; - // static unsigned int selectBuf[16384]; - 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); - 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 fcnt=0; - FaceIterator fi; - for(fi=m.face.begin();fi!=m.face.end();++fi) - { - if(!(*fi).IsD()) - { - glLoadName(fcnt); - glBegin(GL_TRIANGLES); - glVertex( (*fi).V(0)->P() ); - glVertex( (*fi).V(1)->P() ); - glVertex( (*fi).V(2)->P() ); - glEnd(); - } - fcnt++; // the counter should advance even for deleted faces! - } - - glPopMatrix(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - hits = glRenderMode(GL_RENDER); - //xstring buf; - //if (hits <= 0) return 0; - std::vector< std::pair > H; - for(long ii=0;ii(selectBuf[ii*4+1]/4294967295.0,selectBuf[ii*4+3])); - } - if(sorted) - std::sort(H.begin(),H.end()); - // if(H.size()>0) TRACE("\n Closest is %i\n",H[0].second); - result.resize(H.size()); - for(long ii=0;ii &result, int width=4, int height=4,bool sorted=true) - { - result.clear(); - if(width==0 ||height==0) return 0; - long hits; - int sz=m.vert.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); - glMatrixMode(GL_PROJECTION); - glGetDoublev(GL_PROJECTION_MATRIX ,mp); - glPushMatrix(); - glLoadIdentity(); - gluPickMatrix(x, y, width, height, viewport); - glMultMatrixd(mp); - - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - int vcnt=0; - VertexIterator vi; - for(vi=m.vert.begin();vi!=m.vert.end();++vi) - { - if(!(*vi).IsD()) - { - glLoadName(vcnt); - glBegin(GL_POINTS); - glVertex( (*vi).P() ); - glEnd(); - } - vcnt++; // the counter should advance even for deleted faces! - } - - glPopMatrix(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - hits = glRenderMode(GL_RENDER); - std::vector< std::pair > H; - for(long ii=0;ii(selectBuf[ii*4+1]/4294967295.0,selectBuf[ii*4+3])); - } - if(sorted) - std::sort(H.begin(),H.end()); - result.resize(H.size()); - for(long ii=0;ii