MeshNodeT.cc

00001 /*===========================================================================*\
00002  *                                                                           *
00003  *                              OpenFlipper                                  *
00004  *      Copyright (C) 2001-2009 by Computer Graphics Group, RWTH Aachen      *
00005  *                           www.openflipper.org                             *
00006  *                                                                           *
00007  *---------------------------------------------------------------------------*
00008  *  This file is part of OpenFlipper.                                        *
00009  *                                                                           *
00010  *  OpenFlipper is free software: you can redistribute it and/or modify      *
00011  *  it under the terms of the GNU Lesser General Public License as           *
00012  *  published by the Free Software Foundation, either version 3 of           *
00013  *  the License, or (at your option) any later version with the              *
00014  *  following exceptions:                                                    *
00015  *                                                                           *
00016  *  If other files instantiate templates or use macros                       *
00017  *  or inline functions from this file, or you compile this file and         *
00018  *  link it with other files to produce an executable, this file does        *
00019  *  not by itself cause the resulting executable to be covered by the        *
00020  *  GNU Lesser General Public License. This exception does not however       *
00021  *  invalidate any other reasons why the executable file might be            *
00022  *  covered by the GNU Lesser General Public License.                        *
00023  *                                                                           *
00024  *  OpenFlipper is distributed in the hope that it will be useful,           *
00025  *  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
00026  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
00027  *  GNU Lesser General Public License for more details.                      *
00028  *                                                                           *
00029  *  You should have received a copy of the GNU LesserGeneral Public          *
00030  *  License along with OpenFlipper. If not,                                  *
00031  *  see <http://www.gnu.org/licenses/>.                                      *
00032  *                                                                           *
00033 \*===========================================================================*/
00034 
00035 /*===========================================================================*\
00036  *                                                                           *
00037  *   $Revision: 6743 $                                                       *
00038  *   $Author: moebius $                                                      *
00039  *   $Date: 2009-08-05 11:03:10 +0200 (Mi, 05. Aug 2009) $                   *
00040  *                                                                           *
00041 \*===========================================================================*/
00042 
00043 
00044 
00045 
00046 //=============================================================================
00047 //
00048 //  CLASS MeshNodeT - IMPLEMENTATION
00049 //
00050 //=============================================================================
00051 
00052 #define ACG_MESHNODE_C
00053 
00054 //== INCLUDES =================================================================
00055 
00056 
00057 #include "MeshNodeT.hh"
00058 #include "ShaderNode.hh"
00059 #include "DrawModes.hh"
00060 #include "../GL/gl.hh"
00061 #include "../GL/ColorTranslator.hh"
00062 
00063 #include <OpenMesh/Core/System/omstream.hh>
00064 #include <OpenMesh/Core/Utils/Property.hh>
00065 
00066 //== NAMESPACES ==============================================================
00067 
00068 
00069 namespace ACG {
00070 namespace SceneGraph {
00071 
00072 
00073 //== IMPLEMENTATION ==========================================================
00074 
00075 
00076 template<class Mesh>
00077 MeshNodeT<Mesh>::
00078 MeshNodeT(const Mesh&  _mesh,
00079           BaseNode*    _parent,
00080           std::string  _name)
00081   : BaseNode(_parent, _name),
00082     mesh_(_mesh),
00083     enabled_arrays_(0),
00084     face_index_buffer_(0),
00085     vertex_buffer_(0),
00086     normal_buffer_(0),
00087     vertexBufferInitialized_(false),
00088     normalBufferInitialized_(false),
00089     faceIndexBufferInitialized_(false),
00090     textureMap_(0),
00091     propertyMap_(0),
00092     default_halfedge_textcoord_property_("h:texcoords2D"),
00093     indexPropertyName_("f:textureindex"),
00094     updateFaceList_(true),
00095     updateVertexList_(true),
00096     updateEdgeList_(true),
00097     updateAnyList_(true),
00098     faceBaseIndex_(0),
00099     vertexBaseIndex_(0),
00100     edgeBaseIndex_(0),
00101     anyBaseIndex_(0),
00102     bbMin_(FLT_MAX,  FLT_MAX,  FLT_MAX),
00103     bbMax_(-FLT_MAX, -FLT_MAX, -FLT_MAX)
00104 {
00105   faceList_ = glGenLists (1);
00106   vertexList_ = glGenLists (1);
00107   edgeList_ = glGenLists (1);
00108   anyList_ = glGenLists (3);
00109 }
00110 
00111 
00112 //----------------------------------------------------------------------------
00113 
00114 
00115 template<class Mesh>
00116 MeshNodeT<Mesh>::
00117 ~MeshNodeT()
00118 {
00119   if (vertex_buffer_)
00120     glDeleteBuffersARB(1, (GLuint*) &vertex_buffer_);
00121 
00122   if (normal_buffer_)
00123     glDeleteBuffersARB(1, (GLuint*)  &normal_buffer_);
00124 
00125   if (face_index_buffer_)
00126     glDeleteBuffersARB(1, (GLuint*)  &face_index_buffer_ );
00127 
00128   if (faceList_)
00129     glDeleteLists (faceList_, 1);
00130 
00131   if (vertexList_)
00132     glDeleteLists (vertexList_, 1);
00133 
00134   if (edgeList_)
00135     glDeleteLists (edgeList_, 1);
00136 
00137   if (anyList_)
00138     glDeleteLists (anyList_, 3);
00139 }
00140 
00141 
00142 //----------------------------------------------------------------------------
00143 
00144 
00145 template<class Mesh>
00146 void
00147 MeshNodeT<Mesh>::
00148 boundingBox(Vec3f& _bbMin, Vec3f& _bbMax)
00149 {
00150   _bbMin.minimize(bbMin_);
00151   _bbMax.maximize(bbMax_);
00152 }
00153 
00154 
00155 //----------------------------------------------------------------------------
00156 
00157 
00158 template<class Mesh>
00159 unsigned int
00160 MeshNodeT<Mesh>::
00161 availableDrawModes() const
00162 {
00163   unsigned int drawModes(0);
00164 
00165   drawModes |= DrawModes::POINTS;
00166   drawModes |= DrawModes::WIREFRAME;
00167   drawModes |= DrawModes::HIDDENLINE;
00168   drawModes |= DrawModes::SOLID_SHADER;
00169 
00170   if (mesh_.has_vertex_normals())
00171   {
00172     drawModes |= DrawModes::POINTS_SHADED;
00173     drawModes |= DrawModes::SOLID_SMOOTH_SHADED;
00174     drawModes |= DrawModes::SOLID_PHONG_SHADED;
00175   }
00176 
00177   if (mesh_.has_vertex_colors())
00178   {
00179     drawModes |= DrawModes::POINTS_COLORED;
00180     drawModes |= DrawModes::SOLID_POINTS_COLORED;
00181   }
00182 
00183   if (mesh_.has_face_normals())
00184     drawModes |= DrawModes::SOLID_FLAT_SHADED;
00185 
00186   if (mesh_.has_face_colors())
00187   {
00188     drawModes |= DrawModes::SOLID_FACES_COLORED;
00189 
00190     if( mesh_.has_face_normals() )
00191            drawModes |= DrawModes::SOLID_FACES_COLORED_FLAT_SHADED;
00192   }
00193 
00194   if (mesh_.has_vertex_texcoords1D())
00195   {
00196     drawModes |= DrawModes::SOLID_1DTEXTURED;
00197 
00198     if (mesh_.has_vertex_normals())
00199       drawModes |= DrawModes::SOLID_1DTEXTURED_SHADED;
00200   }
00201 
00202   if (mesh_.has_vertex_texcoords2D())
00203   {
00204     drawModes |= DrawModes::SOLID_TEXTURED;
00205 
00206     if (mesh_.has_vertex_normals())
00207       drawModes |= DrawModes::SOLID_TEXTURED_SHADED;
00208   }
00209 
00210   if (mesh_.has_vertex_texcoords3D())
00211   {
00212     drawModes |= DrawModes::SOLID_3DTEXTURED;
00213 
00214     if (mesh_.has_vertex_normals())
00215       drawModes |= DrawModes::SOLID_3DTEXTURED_SHADED;
00216   }
00217 
00218   if (mesh_.has_halfedge_texcoords2D())
00219   {
00220     drawModes |= DrawModes::SOLID_2DTEXTURED_FACE;
00221     if (mesh_.has_face_normals())
00222       drawModes |= DrawModes::SOLID_2DTEXTURED_FACE_SHADED;
00223   }
00224 
00225   return drawModes;
00226 }
00227 
00228 
00229 //----------------------------------------------------------------------------
00230 
00231 
00232 template<class Mesh>
00233 void
00234 MeshNodeT<Mesh>::
00235 enable_arrays(unsigned int _arrays)
00236 {
00237   // special case: VBO
00238   // only use for float data, otherwise it's terribly slow!
00239   typedef typename Mesh::Point         Point;
00240   typedef typename Point::value_type   PointScalar;
00241   typedef typename Mesh::Normal        Normal;
00242   typedef typename Normal::value_type  NormalScalar;
00243 
00244   bool use_vbo =
00245     ((_arrays == VERTEX_ARRAY || _arrays == (VERTEX_ARRAY | NORMAL_ARRAY)) &&
00246      (vertexBufferInitialized_ && normalBufferInitialized_) ) ;
00247 //   omlog() << "Use VBO: " << use_vbo << std::endl;
00248 
00249 
00250 
00251   // unbind VBO buffers
00252   if (!use_vbo && vertex_buffer_)
00253     glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
00254 
00255 
00256 
00257   if (_arrays & VERTEX_ARRAY)
00258   {
00259     if (!(enabled_arrays_ & VERTEX_ARRAY))
00260     {
00261       enabled_arrays_ |= VERTEX_ARRAY;
00262       glEnableClientState(GL_VERTEX_ARRAY);
00263 
00264       if (use_vbo )
00265       {
00266          glBindBufferARB(GL_ARRAY_BUFFER_ARB, vertex_buffer_);
00267 
00268          // As we ensure that buffers are converted to float before using them, use Float here
00269          glVertexPointer(3, GL_FLOAT, 0, 0);
00270       }
00271       else
00272       {
00273          glVertexPointer(mesh_.points());
00274       }
00275     }
00276   }
00277   else if (enabled_arrays_ & VERTEX_ARRAY)
00278   {
00279     enabled_arrays_ &= ~VERTEX_ARRAY;
00280     glDisableClientState(GL_VERTEX_ARRAY);
00281   }
00282 
00283 
00284   if (_arrays & NORMAL_ARRAY)
00285   {
00286     if (!(enabled_arrays_ & NORMAL_ARRAY))
00287     {
00288       enabled_arrays_ |= NORMAL_ARRAY;
00289       glEnableClientState(GL_NORMAL_ARRAY);
00290 
00291       if (use_vbo)
00292       {
00293          glBindBufferARB(GL_ARRAY_BUFFER_ARB, normal_buffer_);
00294 
00295          // As we ensure that buffers are converted to float before using them, use Float here
00296          glNormalPointer(GL_FLOAT, 0 , 0);
00297       }
00298       else
00299       {
00300          glNormalPointer(mesh_.vertex_normals());
00301       }
00302     }
00303   }
00304   else if (enabled_arrays_ & NORMAL_ARRAY)
00305   {
00306     enabled_arrays_ &= ~NORMAL_ARRAY;
00307     glDisableClientState(GL_NORMAL_ARRAY);
00308   }
00309 
00310 
00311   if (_arrays & COLOR_ARRAY)
00312   {
00313     if (!(enabled_arrays_ & COLOR_ARRAY))
00314     {
00315       enabled_arrays_ |= COLOR_ARRAY;
00316       glEnableClientState(GL_COLOR_ARRAY);
00317       glColorPointer(mesh_.vertex_colors());
00318     }
00319   }
00320   else if (enabled_arrays_ & COLOR_ARRAY)
00321   {
00322     enabled_arrays_ &= ~COLOR_ARRAY;
00323     glDisableClientState(GL_COLOR_ARRAY);
00324   }
00325 
00326 
00327   if (_arrays & TEXTURE_COORD_1D_ARRAY)
00328   {
00329     if (!(enabled_arrays_ & TEXTURE_COORD_1D_ARRAY))
00330     {
00331       enabled_arrays_ |= TEXTURE_COORD_1D_ARRAY;
00332       glEnableClientState(GL_TEXTURE_COORD_ARRAY);
00333       glTexCoordPointer(mesh_.texcoords1D());
00334     }
00335   }
00336   else if (enabled_arrays_ & TEXTURE_COORD_1D_ARRAY)
00337   {
00338     enabled_arrays_ &= ~TEXTURE_COORD_1D_ARRAY;
00339     glDisableClientState(GL_TEXTURE_COORD_ARRAY);
00340   }
00341 
00342 
00343   if (_arrays & TEXTURE_COORD_2D_ARRAY)
00344   {
00345     if (!(enabled_arrays_ & TEXTURE_COORD_2D_ARRAY))
00346     {
00347       enabled_arrays_ |= TEXTURE_COORD_2D_ARRAY;
00348       glEnableClientState(GL_TEXTURE_COORD_ARRAY);
00349       glTexCoordPointer(mesh_.texcoords2D());
00350     }
00351   }
00352   else if (enabled_arrays_ & TEXTURE_COORD_2D_ARRAY)
00353   {
00354     enabled_arrays_ &= ~TEXTURE_COORD_2D_ARRAY;
00355     glDisableClientState(GL_TEXTURE_COORD_ARRAY);
00356   }
00357 
00358 
00359   if (_arrays & TEXTURE_COORD_3D_ARRAY)
00360   {
00361     if (!(enabled_arrays_ & TEXTURE_COORD_3D_ARRAY))
00362     {
00363       enabled_arrays_ |= TEXTURE_COORD_3D_ARRAY;
00364       glEnableClientState(GL_TEXTURE_COORD_ARRAY);
00365       glTexCoordPointer(mesh_.texcoords3D());
00366     }
00367   }
00368   else if (enabled_arrays_ & TEXTURE_COORD_3D_ARRAY)
00369   {
00370     enabled_arrays_ &= ~TEXTURE_COORD_3D_ARRAY;
00371     glDisableClientState(GL_TEXTURE_COORD_ARRAY);
00372   }
00373 
00374 
00375   glCheckErrors();
00376 }
00377 
00378 
00379 //----------------------------------------------------------------------------
00380 
00381 
00382 template<class Mesh>
00383 void
00384 MeshNodeT<Mesh>::
00385 update_geometry()
00386 {
00387   updateFaceList_ = true;
00388   updateVertexList_ = true;
00389   updateEdgeList_ = true;
00390   updateAnyList_ = true;
00391 
00392   bbMin_ = Vec3f(FLT_MAX,  FLT_MAX,  FLT_MAX);
00393   bbMax_ = Vec3f(-FLT_MAX, -FLT_MAX, -FLT_MAX);
00394   typename Mesh::ConstVertexIter  v_it(mesh_.vertices_begin()),
00395                                   v_end(mesh_.vertices_end());
00396 
00397   for (; v_it!=v_end; ++v_it)
00398   {
00399     bbMin_.minimize((Vec3f)mesh_.point(v_it));
00400     bbMax_.maximize((Vec3f)mesh_.point(v_it));
00401   }
00402 
00403   if (GLEW_ARB_vertex_buffer_object) {
00404     typedef typename Mesh::Point         Point;
00405     typedef typename Point::value_type   PointScalar;
00406     typedef typename Mesh::Normal        Normal;
00407     typedef typename Normal::value_type  NormalScalar;
00408 
00409     //===================================================================
00410     // Generate a vertex buffer on the GPU
00411     //===================================================================
00412 
00413     if (!vertex_buffer_)  glGenBuffersARB(1,  (GLuint*) &vertex_buffer_);
00414 
00415     glBindBufferARB(GL_ARRAY_BUFFER_ARB, vertex_buffer_);
00416     vertexBufferInitialized_ = false;
00417 
00418     //Check if using floats otherwise convert to internal float array
00419     if ( sizeof(PointScalar) == 4 ) {
00420 
00421       glBufferDataARB(GL_ARRAY_BUFFER_ARB,
00422                       3 * mesh_.n_vertices() * sizeof(PointScalar),
00423                       mesh_.points(),
00424                       GL_STATIC_DRAW_ARB);
00425 
00426       vertexBufferInitialized_ = true;
00427 
00428     } else {
00429 
00430       vertices_.clear();
00431       typename Mesh::ConstVertexIter v_it(mesh_.vertices_begin()),
00432                                      v_end(mesh_.vertices_end());
00433 
00434       for ( ; v_it != v_end ; ++v_it )
00435         vertices_.push_back( ACG::Vec3f(mesh_.point(v_it)) );
00436 
00437            if ( !vertices_.empty() ) {
00438 
00439                   glBufferDataARB(GL_ARRAY_BUFFER_ARB,
00440                                                  3 * mesh_.n_vertices() * sizeof(float),
00441                                                       &vertices_[0],
00442                                                       GL_STATIC_DRAW_ARB);
00443         vertexBufferInitialized_ = true;
00444 
00445       }
00446     }
00447 
00448     //===================================================================
00449     // Generate a normal buffer on the GPU
00450     //===================================================================
00451 
00452     if (!normal_buffer_)  glGenBuffersARB(1,  (GLuint*)  &normal_buffer_);
00453     glBindBufferARB(GL_ARRAY_BUFFER_ARB, normal_buffer_);
00454     normalBufferInitialized_ = false;
00455 
00456     // Check if using floats otherwise convert to internal float array
00457     if ( sizeof(NormalScalar) == 4) {
00458 
00459       glBufferDataARB(GL_ARRAY_BUFFER_ARB,
00460                       3 * mesh_.n_vertices() * sizeof(NormalScalar),
00461                       mesh_.vertex_normals(),
00462                       GL_STATIC_DRAW_ARB);
00463 
00464       normalBufferInitialized_ = true;
00465 
00466     } else {
00467       normals_.clear();
00468       typename Mesh::ConstVertexIter v_it(mesh_.vertices_begin()),
00469                                      v_end(mesh_.vertices_end());
00470 
00471       for ( ; v_it != v_end ; ++v_it )
00472         normals_.push_back( ACG::Vec3f(mesh_.normal(v_it)) );
00473 
00474           if ( !normals_.empty() ) {
00475 
00476          glBufferDataARB(GL_ARRAY_BUFFER_ARB,
00477                          3 * mesh_.n_vertices() * sizeof(float),
00478                                                        &normals_[0],
00479                                                        GL_STATIC_DRAW_ARB);
00480                          normalBufferInitialized_ = true;
00481      }
00482 
00483     }
00484 
00485     // unbind buffers
00486     glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
00487 
00488   } else omlog() << "MeshNodeT: VBO not supported on this machine\n";
00489 }
00490 
00491 
00492 //----------------------------------------------------------------------------
00493 
00494 
00495 template<class Mesh>
00496 void
00497 MeshNodeT<Mesh>::
00498 update_topology()
00499 {
00500   updateFaceList_ = true;
00501   updateVertexList_ = true;
00502 
00503   if (mesh_.is_trimesh())
00504   {
00505     typename Mesh::ConstFaceIter        f_it(mesh_.faces_sbegin()),
00506                                         f_end(mesh_.faces_end());
00507     typename Mesh::ConstFaceVertexIter  fv_it;
00508 
00509     try
00510     {
00511       indices_.clear();
00512       std::vector<unsigned int>().swap(indices_);
00513       indices_.reserve(mesh_.n_faces()*3);
00514 
00515       for (; f_it!=f_end; ++f_it)
00516       {
00517              indices_.push_back((fv_it=mesh_.cfv_iter(f_it)).handle().idx());
00518              indices_.push_back((++fv_it).handle().idx());
00519              indices_.push_back((++fv_it).handle().idx());
00520       }
00521     }
00522     catch (...)
00523     {
00524       indices_.clear();
00525       std::vector<unsigned int>().swap(indices_);
00526       omerr() << "Topology caching failed\n";
00527     }
00528 
00529     //===================================================================
00530     // Generate an index buffer on the GPU
00531     //===================================================================
00532     faceIndexBufferInitialized_ = false;
00533 
00534     if ( GLEW_ARB_vertex_buffer_object && !indices_.empty() ) {
00535 
00536       // generate buffer
00537       if (!face_index_buffer_)  glGenBuffersARB(1,  (GLuint*)  &face_index_buffer_);
00538 
00539       // index buffer
00540       glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, face_index_buffer_);
00541 
00542       glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB,
00543                       indices_.size() * sizeof(unsigned int),
00544                       &indices_[0],
00545                       GL_STATIC_DRAW_ARB);
00546 
00547       faceIndexBufferInitialized_ = true;
00548 
00549       // unbind buffer
00550       glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
00551 
00552     }
00553 
00554   }
00555 
00556 }
00557 
00558 
00559 //----------------------------------------------------------------------------
00560 
00561 
00562 template<class Mesh>
00563 void
00564 MeshNodeT<Mesh>::
00565 draw(GLState& _state, unsigned int _drawMode)
00566 {
00567   glDepthFunc(depthFunc());
00568 
00569 
00570   if (_drawMode & DrawModes::POINTS)
00571   {
00572     enable_arrays(VERTEX_ARRAY);
00573     glDisable(GL_LIGHTING);
00574     glShadeModel(GL_FLAT);
00575     draw_vertices();
00576   }
00577 
00578 
00579   if ( ( _drawMode & DrawModes::POINTS_COLORED ) && mesh_.has_vertex_colors())
00580   {
00581     enable_arrays(VERTEX_ARRAY | COLOR_ARRAY);
00582     glDisable(GL_LIGHTING);
00583     glShadeModel(GL_FLAT);
00584     draw_vertices();
00585   }
00586 
00587 
00588   if ( ( _drawMode & DrawModes::POINTS_SHADED ) && mesh_.has_vertex_normals())
00589   {
00590     enable_arrays(VERTEX_ARRAY | NORMAL_ARRAY);
00591     glEnable(GL_LIGHTING);
00592     glShadeModel(GL_FLAT);
00593     draw_vertices();
00594   }
00595 
00596 
00597   if (_drawMode & DrawModes::WIREFRAME)
00598   {
00599     glPushAttrib(GL_ENABLE_BIT);
00600 
00601     glDisable( GL_CULL_FACE );
00602 
00603     enable_arrays(VERTEX_ARRAY);
00604     glDisable(GL_LIGHTING);
00605     glShadeModel(GL_FLAT);
00606     glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
00607     draw_faces(PER_VERTEX);
00608     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00609 
00610     glPopAttrib();
00611   }
00612 
00613 
00614   if (_drawMode & DrawModes::HIDDENLINE)
00615   {
00616     enable_arrays(VERTEX_ARRAY);
00617 
00618     Vec4f  clear_color = _state.clear_color();
00619     Vec4f  base_color  = _state.base_color();
00620     clear_color[3] = 1.0;
00621 
00622     glDisable(GL_LIGHTING);
00623     glShadeModel(GL_FLAT);
00624     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00625     _state.set_base_color(clear_color);
00626 
00627     glDepthRange(0.01, 1.0);
00628     draw_faces(PER_VERTEX);
00629     glDepthRange(0.0, 1.0);
00630 
00631     glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
00632     glDepthFunc(GL_LEQUAL);
00633     _state.set_base_color(base_color);
00634     draw_faces(PER_VERTEX);
00635     glDepthFunc(depthFunc());
00636     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00637   }
00638 
00639 
00640   if ( ( _drawMode & DrawModes::SOLID_FLAT_SHADED ) && mesh_.has_face_normals())
00641   {
00642     glEnable(GL_LIGHTING);
00643     glShadeModel(GL_FLAT);
00644     glDepthRange(0.01, 1.0);
00645     draw_faces(FACE_NORMALS);
00646     glDepthRange(0.0, 1.0);
00647   }
00648 
00649 
00650   if ( ( _drawMode & DrawModes::SOLID_SMOOTH_SHADED ) && mesh_.has_vertex_normals())
00651   {
00652     enable_arrays(VERTEX_ARRAY | NORMAL_ARRAY);
00653     glEnable(GL_LIGHTING);
00654     glShadeModel(GL_SMOOTH);
00655     glDepthRange(0.01, 1.0);
00656     draw_faces(PER_VERTEX);
00657     glDepthRange(0.0, 1.0);
00658   }
00659 
00660   if ( ( _drawMode & DrawModes::SOLID_PHONG_SHADED ) && mesh_.has_vertex_normals() )
00661   {
00662 //     if ( parent() != 0 ) {
00663 //       if ( parent()->className() == "ShaderNode" ) {
00664 //
00665 //         ShaderNode* node = dynamic_cast< ShaderNode* > ( parent() );
00666 //
00667 //         GLSL::PtrProgram program = node->getShader( DrawModes::SOLID_PHONG_SHADED );
00668 //
00669 //         // Enable own Phong shader
00670 //         program->use();
00671 
00672         enable_arrays(VERTEX_ARRAY | NORMAL_ARRAY);
00673         glEnable(GL_LIGHTING);
00674         glShadeModel(GL_SMOOTH);
00675         glDepthRange(0.01, 1.0);
00676         draw_faces(PER_VERTEX);
00677         glDepthRange(0.0, 1.0);
00678 
00679         //disable own Phong shader
00680 //         program->disable();
00681 //       }
00682 //     }
00683   }
00684 
00685   if ( ( _drawMode & DrawModes::SOLID_ENV_MAPPED ) && mesh_.has_vertex_normals())
00686   {
00687     enable_arrays(VERTEX_ARRAY | NORMAL_ARRAY);
00688     glEnable(GL_LIGHTING);
00689     glShadeModel(GL_SMOOTH);
00690     glDepthRange(0.01, 1.0);
00691     draw_faces(PER_VERTEX);
00692     glDepthRange(0.0, 1.0);
00693   }
00694 
00695 
00696   if ( ( _drawMode & DrawModes::SOLID_FACES_COLORED )&& mesh_.has_face_colors())
00697   {
00698     Vec4f base_color_backup = _state.base_color();
00699 
00700     glDisable(GL_LIGHTING);
00701     glShadeModel(GL_FLAT);
00702     glDepthRange(0.01, 1.0);
00703     draw_faces(FACE_COLORS);
00704     glDepthRange(0.0, 1.0);
00705 
00706     _state.set_base_color(base_color_backup);
00707   }
00708 
00709 
00710   if ( ( _drawMode & DrawModes::SOLID_FACES_COLORED_FLAT_SHADED ) && mesh_.has_face_colors() && mesh_.has_face_normals())
00711   {
00712     Vec4f base_color_backup = _state.base_color();
00713     glEnable(GL_LIGHTING);
00714 
00715     glShadeModel(GL_FLAT);
00716     glDepthRange(0.01, 1.0);
00717     draw_faces(FACE_NORMALS_COLORS);
00718     glDepthRange(0.0, 1.0);
00719 
00720     _state.set_base_color(base_color_backup);
00721   }
00722 
00723 
00724   if ( ( _drawMode & DrawModes::SOLID_POINTS_COLORED ) && mesh_.has_vertex_colors())
00725   {
00726     Vec4f base_color_backup = _state.base_color();
00727 
00728     enable_arrays(VERTEX_ARRAY | COLOR_ARRAY);
00729     glDisable(GL_LIGHTING);
00730     glShadeModel(GL_SMOOTH);
00731     glDepthRange(0.01, 1.0);
00732     draw_faces(PER_VERTEX);
00733     glDepthRange(0.0, 1.0);
00734 
00735     _state.set_base_color(base_color_backup);
00736   }
00737 
00738 
00739   if ( ( _drawMode & DrawModes::SOLID_TEXTURED ) && mesh_.has_vertex_texcoords2D())
00740   {
00741     enable_arrays(VERTEX_ARRAY | TEXTURE_COORD_2D_ARRAY);
00742     glEnable(GL_TEXTURE_2D);
00743     glDisable(GL_LIGHTING);
00744     glShadeModel(GL_FLAT);
00745     glDepthRange(0.01, 1.0);
00746     draw_faces(PER_VERTEX);
00747     glDepthRange(0.0, 1.0);
00748     glDisable(GL_TEXTURE_2D);
00749   }
00750 
00751 
00752   if ( ( _drawMode & DrawModes::SOLID_TEXTURED_SHADED ) && mesh_.has_vertex_texcoords2D() && mesh_.has_vertex_normals())
00753   {
00754     enable_arrays(VERTEX_ARRAY | NORMAL_ARRAY | TEXTURE_COORD_2D_ARRAY);
00755     glEnable(GL_TEXTURE_2D);
00756     glEnable(GL_LIGHTING);
00757     glShadeModel(GL_SMOOTH);
00758     glDepthRange(0.01, 1.0);
00759     draw_faces(PER_VERTEX);
00760     glDepthRange(0.0, 1.0);
00761     glDisable(GL_TEXTURE_2D);
00762   }
00763 
00764 
00765   if ( ( _drawMode & DrawModes::SOLID_1DTEXTURED ) && mesh_.has_vertex_texcoords1D())
00766   {
00767     enable_arrays(VERTEX_ARRAY | TEXTURE_COORD_1D_ARRAY);
00768     glEnable(GL_TEXTURE_1D);
00769     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
00770     glDisable(GL_LIGHTING);
00771     glShadeModel(GL_SMOOTH);
00772     glDepthRange(0.01, 1.0);
00773     draw_faces(PER_VERTEX);
00774     glDepthRange(0.0, 1.0);
00775     glDisable(GL_TEXTURE_1D);
00776   }
00777 
00778 
00779   if ( ( _drawMode & DrawModes::SOLID_1DTEXTURED_SHADED ) && mesh_.has_vertex_texcoords1D() && mesh_.has_vertex_normals())
00780   {
00781     // store and change colors
00782     const Vec4f ambient  = _state.ambient_color();
00783     const Vec4f diffuse  = _state.diffuse_color();
00784     const Vec4f specular = _state.specular_color();
00785     _state.set_ambient_color  (Vec4f(0.1, 0.1, 0.1, 1.0));
00786     _state.set_diffuse_color  (Vec4f(0.8, 0.8, 0.8, 1.0));
00787     _state.set_specular_color (Vec4f(1.0, 1.0, 1.0, 1.0));
00788 
00789     // store and change texture mode
00790     GLint texmode;
00791     glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &texmode);
00792     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
00793 
00794     enable_arrays(VERTEX_ARRAY | NORMAL_ARRAY | TEXTURE_COORD_1D_ARRAY);
00795     glEnable(GL_TEXTURE_1D);
00796     glEnable(GL_LIGHTING);
00797     glShadeModel(GL_SMOOTH);
00798     glDepthRange(0.01, 1.0);
00799     draw_faces(PER_VERTEX);
00800     glDepthRange(0.0, 1.0);
00801     glDisable(GL_TEXTURE_1D);
00802 
00803     // restore colors
00804     _state.set_ambient_color(ambient);
00805     _state.set_diffuse_color(diffuse);
00806     _state.set_specular_color(specular);
00807 
00808     // restore texture mode
00809     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, texmode);
00810   }
00811 
00812 
00813 
00814   if ( ( _drawMode & DrawModes::SOLID_3DTEXTURED ) && mesh_.has_vertex_texcoords3D())
00815   {
00816     enable_arrays(VERTEX_ARRAY | TEXTURE_COORD_3D_ARRAY);
00817     glEnable(GL_TEXTURE_3D);
00818     glDisable(GL_LIGHTING);
00819     glShadeModel(GL_FLAT);
00820     glDepthRange(0.01, 1.0);
00821     draw_faces(PER_VERTEX);
00822     glDepthRange(0.0, 1.0);
00823     glDisable(GL_TEXTURE_3D);
00824   }
00825 
00826 
00827   if ( ( _drawMode & DrawModes::SOLID_3DTEXTURED_SHADED ) && mesh_.has_vertex_texcoords3D() && mesh_.has_vertex_normals())
00828   {
00829     enable_arrays(VERTEX_ARRAY | NORMAL_ARRAY | TEXTURE_COORD_3D_ARRAY);
00830     glEnable(GL_TEXTURE_3D);
00831     glEnable(GL_LIGHTING);
00832     glShadeModel(GL_SMOOTH);
00833     glDepthRange(0.01, 1.0);
00834     draw_faces(PER_VERTEX);
00835     glDepthRange(0.0, 1.0);
00836     glDisable(GL_TEXTURE_3D);
00837   }
00838 
00839   // Textured by using coordinates stored in halfedges
00840   // TODO: Check not only mesh_.has_halfedge_texcoords2D but check if custom property is available
00841   if ( ( _drawMode & DrawModes::SOLID_2DTEXTURED_FACE ) && mesh_.has_halfedge_texcoords2D())
00842   {
00843     glEnable(GL_TEXTURE_2D);
00844     glDisable(GL_LIGHTING);
00845     glShadeModel(GL_FLAT);
00846     glDepthRange(0.01, 1.0);
00847     draw_faces(FACE_HALFEDGE_TEXTURED);
00848     glDepthRange(0.0, 1.0);
00849     glDisable(GL_TEXTURE_2D);
00850   }
00851 
00852   // Textured by using coordinates stored in halfedges
00853   // TODO: Check not only mesh_.has_halfedge_texcoords2D but check if custom property is available
00854   if ( ( _drawMode & DrawModes::SOLID_2DTEXTURED_FACE_SHADED ) && mesh_.has_halfedge_texcoords2D() && mesh_.has_face_normals())
00855   {
00856     glEnable(GL_TEXTURE_2D);
00857     glEnable(GL_LIGHTING);
00858 
00859     glShadeModel(GL_FLAT);
00860     glDepthRange(0.01, 1.0);
00861     draw_faces(FACE_HALFEDGE_TEXTURED);
00862     glDepthRange(0.0, 1.0);
00863     glDisable(GL_TEXTURE_2D);
00864 
00865   }
00866 
00867   // If in shader mode, just draw, as the shader has to be set by a shadernode above this node
00868   if ( (_drawMode & DrawModes::SOLID_SHADER )  ) {
00869 
00870     if ( mesh_.has_face_normals() )
00871       enable_arrays( VERTEX_ARRAY | NORMAL_ARRAY);
00872     else
00873       enable_arrays( VERTEX_ARRAY );
00874 
00875     glEnable(GL_LIGHTING);
00876     glShadeModel(GL_SMOOTH);
00877     glDepthRange(0.01, 1.0);
00878     draw_faces(PER_VERTEX);
00879     glDepthRange(0.0, 1.0);
00880   }
00881 
00882 
00883   enable_arrays(0);
00884   glDepthFunc(GL_LESS);
00885 }
00886 
00887 
00888 //----------------------------------------------------------------------------
00889 
00890 
00891 template<class Mesh>
00892 void
00893 MeshNodeT<Mesh>::
00894 draw_vertices()
00895 {
00896   glDrawArrays(GL_POINTS, 0, mesh_.n_vertices());
00897 }
00898 
00899 
00900 //----------------------------------------------------------------------------
00901 
00902 
00903 template<class Mesh>
00904 void
00905 MeshNodeT<Mesh>::
00906 draw_faces(FaceMode _mode)
00907 {
00908   typename Mesh::ConstFaceIter        f_it(mesh_.faces_sbegin()),
00909                                       f_end(mesh_.faces_end());
00910   typename Mesh::ConstFaceVertexIter  fv_it;
00911   typename Mesh::ConstFaceHalfedgeIter fh_it;
00912 
00913   switch (_mode)
00914   {
00915     case FACE_NORMALS:
00916     {
00917       if (mesh_.is_trimesh())
00918       {
00919          glBegin(GL_TRIANGLES);
00920          for (; f_it!=f_end; ++f_it)
00921          {
00922             glNormal(mesh_.normal(f_it));
00923             glVertex(mesh_.point(fv_it=mesh_.cfv_iter(f_it)));
00924             glVertex(mesh_.point(++fv_it));
00925             glVertex(mesh_.point(++fv_it));
00926          }
00927          glEnd();
00928       }
00929       else
00930       {
00931          for (; f_it!=f_end; ++f_it)
00932          {
00933             glBegin(GL_POLYGON);
00934             glNormal(mesh_.normal(f_it));
00935             for (fv_it=mesh_.cfv_iter(f_it.handle()); fv_it; ++fv_it)
00936                glVertex(mesh_.point(fv_it));
00937             glEnd();
00938          }
00939       }
00940       break;
00941     }
00942 
00943 
00944     case FACE_COLORS:
00945     {
00946       if (mesh_.is_trimesh())
00947       {
00948          glBegin(GL_TRIANGLES);
00949          for (; f_it!=f_end; ++f_it)
00950          {
00951             glColor(mesh_.color(f_it));
00952             glVertex(mesh_.point(fv_it=mesh_.cfv_iter(f_it)));
00953             glVertex(mesh_.point(++fv_it));
00954             glVertex(mesh_.point(++fv_it));
00955          }
00956          glEnd();
00957       }
00958       else
00959       {
00960          for (; f_it!=f_end; ++f_it)
00961          {
00962             glBegin(GL_POLYGON);
00963             glColor(mesh_.color(f_it));
00964             for (fv_it=mesh_.cfv_iter(f_it.handle()); fv_it; ++fv_it)
00965                glVertex(mesh_.point(fv_it));
00966             glEnd();
00967          }
00968       }
00969       break;
00970     }
00971 
00972 
00973     case FACE_NORMALS_COLORS:
00974     {
00975       if (mesh_.is_trimesh())
00976       {
00977          glBegin(GL_TRIANGLES);
00978          for (; f_it!=f_end; ++f_it)
00979          {
00980             glColor(mesh_.color(f_it));
00981             glNormal(mesh_.normal(f_it));
00982             glVertex(mesh_.point(fv_it=mesh_.cfv_iter(f_it)));
00983             glVertex(mesh_.point(++fv_it));
00984             glVertex(mesh_.point(++fv_it));
00985          }
00986          glEnd();
00987       }
00988       else
00989       {
00990          for (; f_it!=f_end; ++f_it)
00991          {
00992             glBegin(GL_POLYGON);
00993             glColor(mesh_.color(f_it));
00994             glNormal(mesh_.normal(f_it));
00995             for (fv_it=mesh_.cfv_iter(f_it.handle()); fv_it; ++fv_it)
00996                glVertex(mesh_.point(fv_it));
00997             glEnd();
00998          }
00999       }
01000       break;
01001     }
01002 
01003 
01004     // propertyMap_ maps between an int index stored in the Mesh describing which texture to use
01005     // and a property name giving 2D Texture coordinates for halfedges ( texcoords for to vertex )
01006 
01007     case FACE_HALFEDGE_TEXTURED:
01008     {
01009       if (mesh_.is_trimesh())
01010       {
01011 
01012         OpenMesh::FPropHandleT< int > texture_index_property;
01013         if ( !mesh_.get_property_handle(texture_index_property,indexPropertyName_) ) {
01014           if( indexPropertyName_ != "No Texture Index")
01015             std::cerr << "Unable to get per face texture Index property named " << indexPropertyName_ << std::endl;
01016           if ( !mesh_.get_property_handle(texture_index_property,"f:textureindex") ) {
01017             std::cerr << "Unable to get standard per face texture Index property" << std::endl;
01018             texture_index_property.reset();
01019           }
01020         }
01021 
01022         // textureMap_ maps between an int index stored in the Mesh describing which texture to use
01023         // and the GluInt bound by the TextureNode. If such a map is not available, assume TextureNode
01024         // has already bound a texture and we use only one texture.
01025         // Additionally if we do not have an texture index property, we do not know which textures
01026         // should be used .. therefore do not  switch textures if this property is missing.
01027         if ( !textureMap_ || !texture_index_property.is_valid() ) {
01028 
01029           // Get texture coords property
01030           OpenMesh::HPropHandleT< typename Mesh::TexCoord2D > texture_coord_property;
01031           if ( !mesh_.get_property_handle(texture_coord_property,default_halfedge_textcoord_property_) ) {
01032             std::cerr << "Error: Unable to get per face texture coordinate property named "
01033                       << default_halfedge_textcoord_property_ << std::endl;
01034             std::cerr << "Unable to texture without texture coordinates" << std::endl;
01035             return;
01036           }
01037 
01038           typename Mesh::Point point;
01039           typename Mesh::TexCoord2D tex2d;
01040           glBegin(GL_TRIANGLES);
01041           for (; f_it!=f_end; ++f_it) {
01042             glNormal(mesh_.normal(f_it));
01043             for (fh_it = mesh_.cfh_iter(f_it.handle());fh_it;++fh_it) {
01044               point = mesh_.point(mesh_.to_vertex_handle(fh_it));
01045               tex2d = mesh_.property(texture_coord_property,fh_it);
01046               glTexCoord2f(tex2d[0], tex2d[1]);
01047               glVertex(point);
01048             }
01049           }
01050           glEnd();
01051         } else {
01052 
01053           OpenMesh::HPropHandleT< typename Mesh::TexCoord2D > texture_coord_property;
01054           int last_texture = -1;
01055 
01056           typename Mesh::Point point;
01057           typename Mesh::TexCoord2D tex2d;
01058 
01059           for (; f_it!=f_end; ++f_it)
01060           {
01061             int texture = mesh_.property(texture_index_property,f_it);
01062 
01063             if (texture == -1) 
01064               continue;
01065 
01066             if ( last_texture != texture ) {
01067 
01068               if ( textureMap_->find(texture) == textureMap_->end() ) {
01069                 std::cerr << "Illegal texture index ... trying to access " << texture << std::endl;
01070                 last_texture = -1;
01071                 continue;
01072               }
01073 
01074               // Get texture coords property
01075               if ( !propertyMap_ || !mesh_.get_property_handle(texture_coord_property,(*propertyMap_)[texture]) ) {
01076                 if ( propertyMap_)
01077                   std::cerr << "Error: Unable to get per face texture coordinate property named "
01078                             << (*propertyMap_)[texture]  << std::endl;
01079                 if ( !mesh_.get_property_handle(texture_coord_property,"h:texcoords2D") ) {
01080                   std::cerr << "Fallback: Unable to get standard Property for per halfedge texcoords" << std::endl;
01081                   std::cerr << "Unable to texture face without texture coordinates" << std::endl;
01082                   last_texture = -1;
01083                   continue;
01084                 }
01085               }
01086 
01087               glBindTexture( GL_TEXTURE_2D, (*textureMap_)[texture] );
01088 
01089               // Remember active texture to skip extra switches
01090               last_texture = texture;
01091 
01092             }
01093 
01094             glBegin(GL_TRIANGLES);
01095 
01096             glNormal(mesh_.normal(f_it));
01097             glColor(mesh_.color(f_it.handle()));
01098 
01099             for (fh_it = mesh_.cfh_iter(f_it.handle());fh_it;++fh_it)
01100             {
01101               point = mesh_.point(mesh_.to_vertex_handle(fh_it));
01102               tex2d = mesh_.property(texture_coord_property,fh_it);
01103               glTexCoord2f(tex2d[0], tex2d[1]);
01104               glVertex(point);
01105             }
01106 
01107             glEnd();
01108 
01109           }
01110         }
01111       }
01112       else
01113       {
01114         // NOT IMPLEMENTED
01115       }
01116       break;
01117     }
01118 
01119 
01120     case PER_VERTEX:
01121     {
01122       if (mesh_.is_trimesh())
01123       {
01124         // try cached triangle indices
01125         if (!indices_.empty())
01126         {
01127 
01128           // If we have an index buffer on the GPU, use it
01129           if ( faceIndexBufferInitialized_  ) {
01130 
01131             // As we have a list of all faces on the GPU bind it
01132             glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB,face_index_buffer_);
01133 
01134             // Draw it
01135             glDrawElements(GL_TRIANGLES,
01136                            indices_.size(),
01137                            GL_UNSIGNED_INT,
01138                            0);
01139 
01140             // And unbind it again
01141             glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB,0);
01142 
01143           } else {
01144 
01145             glDrawElements(GL_TRIANGLES,
01146                            indices_.size(),
01147                            GL_UNSIGNED_INT,
01148                            &indices_[0]);
01149           }
01150 
01151 
01152         }
01153 
01154         // otherwise use immediate mode
01155         else
01156         {
01157           glBegin(GL_TRIANGLES);
01158           for (; f_it!=f_end; ++f_it)
01159           {
01160             glArrayElement((fv_it=mesh_.cfv_iter(f_it)).handle().idx());
01161             glArrayElement((++fv_it).handle().idx());
01162             glArrayElement((++fv_it).handle().idx());
01163           }
01164           glEnd();
01165         }
01166       }
01167       else
01168       {
01169         for (; f_it!=f_end; ++f_it)
01170         {
01171           glBegin(GL_POLYGON);
01172           for (fv_it=mesh_.cfv_iter(f_it.handle()); fv_it; ++fv_it)
01173             glArrayElement(fv_it.handle().idx());
01174           glEnd();
01175         }
01176       }
01177       break;
01178     }
01179   }
01180 }
01181 
01182 
01183 //----------------------------------------------------------------------------
01184 
01185 
01186 template<class Mesh>
01187 void
01188 MeshNodeT<Mesh>::
01189 pick(GLState& _state, PickTarget _target)
01190 {
01191   switch (_target)
01192   {
01193     case PICK_VERTEX:
01194     {
01195       pick_vertices(_state);
01196       break;
01197     }
01198     case PICK_FRONT_VERTEX:
01199     {
01200       pick_vertices(_state, true);
01201       break;
01202     }
01203 
01204     case PICK_ANYTHING:
01205     {
01206       pick_any(_state);
01207       break;
01208     }
01209     case PICK_FACE:
01210     {
01211       pick_faces(_state);
01212       break;
01213     }
01214 
01215     case PICK_EDGE:
01216     {
01217       pick_edges(_state);
01218       break;
01219     }
01220 
01221     case PICK_FRONT_EDGE:
01222     {
01223       pick_edges(_state, true);
01224       break;
01225     }
01226 
01227     default:
01228       break;
01229   }
01230 }
01231 
01232 
01233 //----------------------------------------------------------------------------
01234 
01235 
01236 template<class Mesh>
01237 void
01238 MeshNodeT<Mesh>::
01239 pick_vertices(GLState& _state, bool _front)
01240 {
01241   typename Mesh::ConstVertexIter v_it(mesh_.vertices_begin()),
01242                                  v_end(mesh_.vertices_end());
01243   GLuint                         idx(0);
01244 
01245   if (!_state.pick_set_maximum (mesh_.n_vertices()))
01246   {
01247     omerr() << "MeshNode::pick_vertices: color range too small, "
01248             << "picking failed\n";
01249     return;
01250   }
01251 
01252   if (_front)
01253   {
01254     enable_arrays(VERTEX_ARRAY);
01255 
01256     Vec4f  clear_color = _state.clear_color();
01257     Vec4f  base_color  = _state.base_color();
01258     clear_color[3] = 1.0;
01259 
01260     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
01261     _state.set_base_color(clear_color);
01262 
01263     glDepthRange(0.01, 1.0);
01264     draw_faces(PER_VERTEX);
01265     glDepthRange(0.0, 1.0);
01266 
01267     glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
01268     glDepthFunc(GL_LEQUAL);
01269     _state.set_base_color(base_color);
01270 
01271     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
01272 
01273     enable_arrays(0);
01274   }
01275 
01276 
01277   if (vertexList_ && !updateVertexList_ && _state.pick_current_index () == vertexBaseIndex_)
01278   {
01279     glCallList (vertexList_);
01280     if (_front)
01281       glDepthFunc(depthFunc());
01282     return;
01283   }
01284 
01285   if (vertexList_)
01286   {
01287     glNewList (vertexList_, GL_COMPILE);
01288     updateVertexList_ = false;
01289     vertexBaseIndex_ = _state.pick_current_index ();
01290   }
01291 
01292   if (_state.color_picking ())
01293   {
01294     update_pick_buffers ();
01295 
01296     for (; v_it!=v_end; ++v_it, ++idx)
01297     {
01298       pickColorBuf_[idx] = _state.pick_get_name_color (idx);
01299       pickVertexBuf_[idx] = mesh_.point(v_it);
01300     }
01301 
01302     glEnableClientState(GL_VERTEX_ARRAY);
01303     glEnableClientState(GL_COLOR_ARRAY);
01304 
01305     glVertexPointer (&pickVertexBuf_[0]);
01306     glColorPointer(&pickColorBuf_[0]);
01307 
01308     glDrawArrays(GL_POINTS, 0, mesh_.n_vertices());
01309 
01310     glDisableClientState(GL_COLOR_ARRAY);
01311     glDisableClientState(GL_VERTEX_ARRAY);
01312   }
01313   else
01314   {
01315     for (; v_it!=v_end; ++v_it, ++idx)
01316     {
01317       _state.pick_set_name (idx);
01318       glBegin(GL_POINTS);
01319       glVertex(mesh_.point(v_it));
01320       glEnd();
01321     }
01322   }
01323 
01324   if (vertexList_)
01325   {
01326     glEndList ();
01327     glCallList (vertexList_);
01328   }
01329 
01330   if (_front)
01331     glDepthFunc(depthFunc());
01332 }
01333 
01334 
01335 //----------------------------------------------------------------------------
01336 
01337 
01338 template<class Mesh>
01339 void
01340 MeshNodeT<Mesh>::
01341 pick_faces(GLState& _state)
01342 {
01343   typename Mesh::ConstFaceIter        f_it(mesh_.faces_sbegin()),
01344                                       f_end(mesh_.faces_end());
01345   typename Mesh::ConstFaceVertexIter  fv_it;
01346 
01347 
01348   if ( mesh_.n_faces() > 0 )
01349   {
01350     if (!_state.pick_set_maximum (mesh_.n_faces()))
01351     {
01352       omerr() << "MeshNode::pick_faces: color range too small, "
01353         << "picking failed\n";
01354       return;
01355     }
01356   }
01357   else
01358   {
01359     if (!_state.pick_set_maximum (1))
01360     {
01361       omerr() << "Strange pickSetMAximum failed for index 1 in MeshNode\n";
01362       return;
01363     }
01364   }
01365 
01366   if (faceList_ && !updateFaceList_ && _state.pick_current_index () == faceBaseIndex_)
01367   {
01368     glCallList (faceList_);
01369     return;
01370   }
01371 
01372   if (faceList_)
01373   {
01374     glNewList (faceList_, GL_COMPILE);
01375     updateFaceList_ = false;
01376     faceBaseIndex_ = _state.pick_current_index ();
01377   }
01378 
01379   if (_state.color_picking ())
01380   {
01381     update_pick_buffers ();
01382     unsigned int idx = 0;
01383 
01384     if (mesh_.is_trimesh())
01385     {
01386       for (; f_it!=f_end; ++f_it)
01387       {
01388         pickColorBuf_[idx]    = _state.pick_get_name_color (f_it.handle().idx());
01389         pickColorBuf_[idx+1]  = _state.pick_get_name_color (f_it.handle().idx());
01390         pickColorBuf_[idx+2]  = _state.pick_get_name_color (f_it.handle().idx());
01391         pickVertexBuf_[idx]   = mesh_.point(fv_it=mesh_.cfv_iter(f_it));
01392         pickVertexBuf_[idx+1] = mesh_.point(++fv_it);
01393         pickVertexBuf_[idx+2] = mesh_.point(++fv_it);
01394         idx += 3;
01395       }
01396 
01397       glEnableClientState(GL_VERTEX_ARRAY);
01398       glEnableClientState(GL_COLOR_ARRAY);
01399 
01400       glVertexPointer (&pickVertexBuf_[0]);
01401       glColorPointer(&pickColorBuf_[0]);
01402 
01403       glDrawArrays(GL_TRIANGLES, 0, mesh_.n_faces() * 3);
01404 
01405       glDisableClientState(GL_COLOR_ARRAY);
01406       glDisableClientState(GL_VERTEX_ARRAY);
01407 
01408     }
01409     else
01410     {
01411       unsigned int face = 0;
01412       std::vector <GLint> first;
01413       std::vector <GLsizei> count;
01414 
01415       first.resize (mesh_.n_faces());
01416       count.resize (mesh_.n_faces());
01417 
01418       for (; f_it!=f_end; ++f_it, ++face)
01419       {
01420         unsigned int cnt = 0;
01421         first[face] = idx;
01422 
01423 
01424         for (fv_it=mesh_.cfv_iter(f_it); fv_it; ++fv_it, ++idx, ++cnt)
01425         {
01426           pickVertexBuf_[idx] = mesh_.point(fv_it);
01427           pickColorBuf_[idx] = _state.pick_get_name_color (f_it.handle().idx());
01428         }
01429         count[face] = cnt; 
01430       }
01431       glEnableClientState(GL_VERTEX_ARRAY);
01432       glEnableClientState(GL_COLOR_ARRAY);
01433 
01434       glVertexPointer (&pickVertexBuf_[0]);
01435       glColorPointer(&pickColorBuf_[0]);
01436 
01437       glMultiDrawArrays(GL_POLYGON, &first[0], &count[0], mesh_.n_faces());
01438 
01439       glDisableClientState(GL_COLOR_ARRAY);
01440       glDisableClientState(GL_VERTEX_ARRAY);
01441     }
01442   }
01443   else
01444   {
01445 
01446     if (mesh_.is_trimesh())
01447     {
01448       for (; f_it!=f_end; ++f_it)
01449       {
01450         // set index
01451         _state.pick_set_name (f_it.handle().idx());
01452 
01453         glBegin(GL_TRIANGLES);
01454         glVertex(mesh_.point(fv_it=mesh_.cfv_iter(f_it)));
01455         glVertex(mesh_.point(++fv_it));
01456         glVertex(mesh_.point(++fv_it));
01457         glEnd();
01458       }
01459     }
01460     else
01461     {
01462       for (; f_it!=f_end; ++f_it)
01463       {
01464         // set index
01465         _state.pick_set_name (f_it.handle().idx());
01466 
01467         glBegin(GL_POLYGON);
01468 
01469         for (fv_it=mesh_.cfv_iter(f_it); fv_it; ++fv_it)
01470                glVertex(mesh_.point(fv_it));
01471 
01472         glEnd();
01473       }
01474     }
01475   }
01476 
01477   if (faceList_)
01478   {
01479     glEndList ();
01480     glCallList (faceList_);
01481   }
01482 }
01483 
01484 //----------------------------------------------------------------------------
01485 
01486 
01487 template<class Mesh>
01488 void
01489 MeshNodeT<Mesh>::
01490 pick_edges(GLState& _state, bool _front)
01491 {
01492   typename Mesh::ConstEdgeIter        e_it(mesh_.edges_sbegin()),
01493                                       e_end(mesh_.edges_end());
01494 
01495   if (!_state.pick_set_maximum (mesh_.n_edges()))
01496   {
01497     omerr() << "MeshNode::pick_edges: color range too small, "
01498             << "picking failed\n";
01499     return;
01500   }
01501 
01502   if (_front)
01503   {
01504     enable_arrays(VERTEX_ARRAY);
01505 
01506     Vec4f  clear_color = _state.clear_color();
01507     Vec4f  base_color  = _state.base_color();
01508     clear_color[3] = 1.0;
01509 
01510     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
01511     _state.set_base_color(clear_color);
01512 
01513     glDepthRange(0.01, 1.0);
01514     draw_faces(PER_VERTEX);
01515     glDepthRange(0.0, 1.0);
01516 
01517     glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
01518     glDepthFunc(GL_LEQUAL);
01519     _state.set_base_color(base_color);
01520 
01521     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
01522 
01523     enable_arrays(0);
01524   }
01525 
01526   if (edgeList_ && !updateEdgeList_ && _state.pick_current_index () == edgeBaseIndex_)
01527   {
01528     glCallList (edgeList_);
01529     if (_front)
01530       glDepthFunc(depthFunc());
01531     return;
01532   }
01533 
01534   if (edgeList_)
01535   {
01536     glNewList (edgeList_, GL_COMPILE);
01537     updateEdgeList_ = false;
01538     edgeBaseIndex_ = _state.pick_current_index ();
01539   }
01540 
01541   if (_state.color_picking ())
01542   {
01543     unsigned int idx = 0;
01544     update_pick_buffers ();
01545 
01546     for (; e_it!=e_end; ++e_it)
01547     {
01548       pickColorBuf_[idx]    = _state.pick_get_name_color (e_it.handle().idx());
01549       pickColorBuf_[idx+1]  = _state.pick_get_name_color (e_it.handle().idx());
01550       pickVertexBuf_[idx]   = mesh_.point(mesh_.to_vertex_handle(mesh_.halfedge_handle(e_it, 0)));
01551       pickVertexBuf_[idx+1] = mesh_.point(mesh_.to_vertex_handle(mesh_.halfedge_handle(e_it, 1)));
01552       idx += 2;
01553     }
01554 
01555     glEnableClientState(GL_VERTEX_ARRAY);
01556     glEnableClientState(GL_COLOR_ARRAY);
01557 
01558     glVertexPointer (&pickVertexBuf_[0]);
01559     glColorPointer(&pickColorBuf_[0]);
01560 
01561     glDrawArrays(GL_LINES, 0, mesh_.n_edges() * 2);
01562 
01563     glDisableClientState(GL_COLOR_ARRAY);
01564     glDisableClientState(GL_VERTEX_ARRAY);
01565   }
01566   else
01567   {
01568     for (; e_it!=e_end; ++e_it)
01569     {
01570       _state.pick_set_name (e_it.handle().idx());
01571       glBegin(GL_LINES);
01572       glVertex(mesh_.point(mesh_.to_vertex_handle(mesh_.halfedge_handle(e_it, 0))));
01573       glVertex(mesh_.point(mesh_.to_vertex_handle(mesh_.halfedge_handle(e_it, 1))));
01574       glEnd();
01575     }
01576   }
01577 
01578   if (edgeList_)
01579   {
01580     glEndList ();
01581     glCallList (edgeList_);
01582   }
01583 
01584   if (_front)
01585     glDepthFunc(depthFunc());
01586 }
01587 
01588 //----------------------------------------------------------------------------
01589 
01590 
01591 template<class Mesh>
01592 void
01593 MeshNodeT<Mesh>::
01594 pick_any(GLState& _state)
01595 {
01596   unsigned int numElements = mesh_.n_faces() + mesh_.n_edges() + mesh_.n_vertices();
01597 
01598   // nothing to pick ?
01599   if (numElements <= 0)
01600     return;
01601 
01602   if (!_state.pick_set_maximum (numElements))
01603   {
01604     omerr() << "MeshNode::pick_any: color range too small, "
01605             << "picking failed\n";
01606     return;
01607   }
01608 
01609   if (anyList_ && !updateAnyList_ && _state.pick_current_index () == anyBaseIndex_)
01610   {
01611     glCallList (anyList_);
01612     glCallList (anyList_+1);
01613     glCallList (anyList_+2);
01614     return;
01615   }
01616 
01617   if (anyList_)
01618   {
01619     glNewList (anyList_, GL_COMPILE);
01620     updateAnyList_ = false;
01621     anyBaseIndex_ = _state.pick_current_index ();
01622   }
01623 
01624   // faces
01625   typename Mesh::ConstFaceIter        f_it(mesh_.faces_sbegin()),
01626                                       f_end(mesh_.faces_end());
01627   typename Mesh::ConstFaceVertexIter  fv_it;
01628 
01629   // edges
01630   typename Mesh::ConstEdgeIter        e_it(mesh_.edges_sbegin()),
01631                                       e_end(mesh_.edges_end());
01632 
01633   // vertices
01634   typename Mesh::ConstVertexIter v_it(mesh_.vertices_begin()),
01635                                  v_end(mesh_.vertices_end());
01636   GLuint                         vidx(mesh_.n_faces() + mesh_.n_edges());
01637 
01638 
01639 
01640   if (_state.color_picking ())
01641   {
01642     update_pick_buffers ();
01643 
01644     glEnableClientState(GL_VERTEX_ARRAY);
01645     glEnableClientState(GL_COLOR_ARRAY);
01646 
01647     // faces
01648     unsigned int idx = 0;
01649     if (mesh_.is_trimesh())
01650     {
01651       for (; f_it!=f_end; ++f_it)
01652       {
01653         pickColorBuf_[idx]    = _state.pick_get_name_color (f_it.handle().idx());
01654         pickColorBuf_[idx+1]  = _state.pick_get_name_color (f_it.handle().idx());
01655         pickColorBuf_[idx+2]  = _state.pick_get_name_color (f_it.handle().idx());
01656         pickVertexBuf_[idx]   = mesh_.point(fv_it=mesh_.cfv_iter(f_it));
01657         pickVertexBuf_[idx+1] = mesh_.point(++fv_it);
01658         pickVertexBuf_[idx+2] = mesh_.point(++fv_it);
01659         idx += 3;
01660       }
01661 
01662       glVertexPointer (&pickVertexBuf_[0]);
01663       glColorPointer(&pickColorBuf_[0]);
01664 
01665       glDrawArrays(GL_TRIANGLES, 0, mesh_.n_faces() * 3);
01666 
01667     }
01668     else
01669     {
01670       unsigned int face = 0;
01671       std::vector <GLint> first;
01672       std::vector <GLsizei> count;
01673 
01674       first.resize (mesh_.n_faces());
01675       count.resize (mesh_.n_faces());
01676 
01677       for (; f_it!=f_end; ++f_it, ++face)
01678       {
01679         unsigned int cnt = 0;
01680         first[face] = idx;
01681 
01682 
01683         for (fv_it=mesh_.cfv_iter(f_it); fv_it; ++fv_it, ++idx, ++cnt)
01684         {
01685           pickVertexBuf_[idx] = mesh_.point(fv_it);
01686           pickColorBuf_[idx] = _state.pick_get_name_color (f_it.handle().idx());
01687         }
01688         count[face] = cnt; 
01689       }
01690 
01691       glVertexPointer (&pickVertexBuf_[0]);
01692       glColorPointer(&pickColorBuf_[0]);
01693 
01694       glMultiDrawArrays(GL_POLYGON, &first[0], &count[0], mesh_.n_faces());
01695 
01696     }
01697 
01698     if (anyList_)
01699     {
01700       glEndList ();
01701       glNewList (anyList_+1, GL_COMPILE);
01702     }
01703 
01704     glDepthFunc(GL_LEQUAL);
01705 
01706     // edges
01707     idx = 0;
01708     for (; e_it!=e_end; ++e_it)
01709     {
01710       pickColorBuf_[idx]    = _state.pick_get_name_color (mesh_.n_faces() + e_it.handle().idx());
01711       pickColorBuf_[idx+1]  = _state.pick_get_name_color (mesh_.n_faces() + e_it.handle().idx());
01712       pickVertexBuf_[idx]   = mesh_.point(mesh_.to_vertex_handle(mesh_.halfedge_handle(e_it, 0)));
01713       pickVertexBuf_[idx+1] = mesh_.point(mesh_.to_vertex_handle(mesh_.halfedge_handle(e_it, 1)));
01714       idx += 2;
01715     }
01716 
01717     glVertexPointer (&pickVertexBuf_[0]);
01718     glColorPointer(&pickColorBuf_[0]);
01719 
01720     glDrawArrays(GL_LINES, 0, mesh_.n_edges() * 2);
01721 
01722     if (anyList_)
01723     {
01724       glEndList ();
01725       glNewList (anyList_+2, GL_COMPILE);
01726     }
01727 
01728     // vertices
01729     idx = 0;
01730     for (; v_it!=v_end; ++v_it, ++idx, ++vidx)
01731     {
01732       pickColorBuf_[idx] = _state.pick_get_name_color (vidx);
01733       pickVertexBuf_[idx] = mesh_.point(v_it);
01734     }
01735 
01736     glVertexPointer (&pickVertexBuf_[0]);
01737     glColorPointer(&pickColorBuf_[0]);
01738 
01739     glDrawArrays(GL_POINTS, 0, mesh_.n_vertices());
01740 
01741     glDisableClientState(GL_COLOR_ARRAY);
01742     glDisableClientState(GL_VERTEX_ARRAY);
01743 
01744     glDepthFunc(depthFunc());
01745   }
01746   else
01747   {
01748     // faces
01749     if (mesh_.is_trimesh())
01750     {
01751       for (; f_it!=f_end; ++f_it)
01752       {
01753         // set index
01754         _state.pick_set_name (f_it.handle().idx());
01755 
01756         glBegin(GL_TRIANGLES);
01757         glVertex(mesh_.point(fv_it=mesh_.cfv_iter(f_it)));
01758         glVertex(mesh_.point(++fv_it));
01759         glVertex(mesh_.point(++fv_it));
01760         glEnd();
01761       }
01762     }
01763     else
01764     {
01765       for (; f_it!=f_end; ++f_it)
01766       {
01767         // set index
01768         _state.pick_set_name (f_it.handle().idx());
01769 
01770         glBegin(GL_POLYGON);
01771 
01772         for (fv_it=mesh_.cfv_iter(f_it); fv_it; ++fv_it)
01773                glVertex(mesh_.point(fv_it));
01774 
01775         glEnd();
01776       }
01777     }
01778 
01779     if (anyList_)
01780     {
01781       glEndList ();
01782       glNewList (anyList_+1, GL_COMPILE);
01783     }
01784 
01785     glDepthFunc(GL_LEQUAL);
01786 
01787     // edges
01788     for (; e_it!=e_end; ++e_it)
01789     {
01790       _state.pick_set_name (mesh_.n_faces() + e_it.handle().idx());
01791       glBegin(GL_LINES);
01792       glVertex(mesh_.point(mesh_.to_vertex_handle(mesh_.halfedge_handle(e_it, 0))));
01793       glVertex(mesh_.point(mesh_.to_vertex_handle(mesh_.halfedge_handle(e_it, 1))));
01794       glEnd();
01795     }
01796 
01797     if (anyList_)
01798     {
01799       glEndList ();
01800       glNewList (anyList_+2, GL_COMPILE);
01801     }
01802 
01803     // vertices
01804     for (; v_it!=v_end; ++v_it, ++vidx)
01805     {
01806       _state.pick_set_name (vidx);
01807       glBegin(GL_POINTS);
01808       glVertex(mesh_.point(v_it));
01809       glEnd();
01810     }
01811 
01812     glDepthFunc(depthFunc());
01813   }
01814 
01815 
01816   if (anyList_)
01817   {
01818     glEndList ();
01819     glCallList (anyList_);
01820     glCallList (anyList_+1);
01821     glCallList (anyList_+2);
01822   }
01823 }
01824 
01825 //----------------------------------------------------------------------------
01826 
01827 template<class Mesh>
01828 void
01829 MeshNodeT<Mesh>::
01830 update_pick_buffers ()
01831 {
01832   unsigned int nfv = 0;
01833   if (mesh_.is_trimesh())
01834     nfv = mesh_.n_faces() * 3;
01835   else
01836   {
01837     // count number of vertices we need for faces in our buffer
01838     typename Mesh::ConstFaceIter    f_it(mesh_.faces_sbegin()),
01839                                     f_end(mesh_.faces_end());
01840     typename Mesh::ConstFaceVertexIter  fv_it;
01841     for (; f_it!=f_end; ++f_it)
01842     {
01843       for (fv_it=mesh_.cfv_iter(f_it); fv_it; ++fv_it)
01844         nfv++;
01845     }
01846   }
01847 
01848   pickVertexBuf_.resize (qMax (mesh_.n_vertices(), qMax (mesh_.n_edges() * 2, nfv)));
01849   pickColorBuf_.resize (qMax (mesh_.n_vertices(), qMax (mesh_.n_edges() * 2, nfv)));
01850 }
01851 
01852 //=============================================================================
01853 } // namespace SceneGraph
01854 } // namespace ACG
01855 //=============================================================================

acg pic Project OpenFlipper, ©  Computer Graphics Group, RWTH Aachen. Documentation generated using doxygen .