OBJNode.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 //  CLASS FastMeshNode - IMPLEMENTATION
00048 //
00049 //=============================================================================
00050 
00051 
00052 //== INCLUDES =================================================================
00053 
00054 
00055 #include "OBJNode.hh"
00056 #include "../GL/gl.hh"
00057 
00058 
00059 //== NAMESPACES ===============================================================
00060 
00061 namespace ACG {
00062 namespace SceneGraph {
00063 
00064 
00065 //== IMPLEMENTATION ========================================================== 
00066 
00067 
00068 void
00069 OBJNode::
00070 boundingBox(Vec3f& _bbMin, Vec3f& _bbMax)
00071 {
00072   for(unsigned int i=0; i<vertices_.size(); ++i)
00073   {
00074     _bbMin.minimize(vertices_[i]);
00075     _bbMax.maximize(vertices_[i]);
00076   }
00077 }
00078 
00079 
00080 //----------------------------------------------------------------------------
00081 
00082   
00083 unsigned int 
00084 OBJNode::
00085 availableDrawModes() const
00086 {
00087   return ( DrawModes::POINTS                 |
00088            DrawModes::WIREFRAME              |
00089            DrawModes::HIDDENLINE             |
00090            DrawModes::SOLID_FLAT_SHADED      |
00091            DrawModes::SOLID_TEXTURED         );
00092 }
00093 
00094 
00095 //----------------------------------------------------------------------------
00096 
00097 
00098 void
00099 OBJNode::
00100 draw(GLState& _state, unsigned int _drawMode)
00101 {
00102   if (_drawMode & DrawModes::POINTS)
00103   {
00104     glDisable(GL_LIGHTING);
00105     glShadeModel(GL_FLAT);
00106     glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
00107     draw_obj();
00108     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00109   }
00110 
00111 
00112   if (_drawMode & DrawModes::WIREFRAME)
00113   {
00114     glDisable(GL_LIGHTING);
00115     glShadeModel(GL_FLAT);
00116     glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
00117     draw_obj();
00118     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00119   }
00120 
00121 
00122   else if (_drawMode & DrawModes::HIDDENLINE)
00123   {
00124     Vec4f base_color_backup = _state.base_color();
00125 
00126     glDisable(GL_LIGHTING);
00127     glShadeModel(GL_FLAT);
00128 
00129     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00130     glColor(_state.clear_color());    
00131     glDepthRange(0.01, 1.0);
00132     draw_obj();
00133 
00134     glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
00135     glColor(base_color_backup);
00136     glDepthRange(0.0, 1.0);
00137     draw_obj();
00138 
00139     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00140   }
00141 
00142 
00143   else if (_drawMode & DrawModes::SOLID_FLAT_SHADED)
00144   {
00145     glEnable(GL_LIGHTING);
00146     glShadeModel(GL_FLAT);
00147     draw_obj();
00148   }
00149 
00150 
00151   else if (_drawMode & DrawModes::SOLID_TEXTURED)
00152   {
00153     glEnable( GL_TEXTURE_2D );    
00154     glDisable(GL_LIGHTING);
00155     glShadeModel(GL_FLAT);
00156     draw_obj_tex();
00157     glDisable( GL_TEXTURE_2D );    
00158   }
00159 }
00160 
00161 
00162 //----------------------------------------------------------------------------
00163 
00164 
00165 void
00166 OBJNode::draw_obj() const
00167 {
00168   glBegin(GL_TRIANGLES);
00169 
00170   for(unsigned int i=0; i<faces_.size(); ++i)
00171   {
00172     glNormal(normals_[i]);      
00173     glVertex(vertices_[faces_[i].i0]);    
00174     glVertex(vertices_[faces_[i].i1]);            
00175     glVertex(vertices_[faces_[i].i2]);
00176   }
00177 
00178   glEnd();
00179 }
00180 
00181 
00182 //----------------------------------------------------------------------------
00183 
00184 
00185 void
00186 OBJNode::draw_obj_tex() const
00187 {
00188   glBegin(GL_TRIANGLES);
00189 
00190   for(unsigned int i=0; i<faces_.size(); ++i)
00191   {
00192     glNormal(normals_[i]);      
00193     if (faces_[i].t0 != -1)
00194     {
00195       glTexCoord(texCoords_[faces_[i].t0]);
00196       glVertex(vertices_[faces_[i].i0]);    
00197       glTexCoord(texCoords_[faces_[i].t1]);
00198       glVertex(vertices_[faces_[i].i1]);            
00199       glTexCoord(texCoords_[faces_[i].t2]);
00200       glVertex(vertices_[faces_[i].i2]);
00201     }
00202     else
00203     {
00204       glVertex(vertices_[faces_[i].i0]);    
00205       glVertex(vertices_[faces_[i].i1]);            
00206       glVertex(vertices_[faces_[i].i2]);
00207     }
00208   }
00209 
00210   glEnd();
00211 }
00212 
00213 
00214 //----------------------------------------------------------------------------
00215 
00216 
00217 void
00218 OBJNode::pick(GLState& _state, PickTarget _target)
00219 {
00220   switch (_target)
00221   {
00222     case PICK_VERTEX:
00223     {
00224       break;
00225     }
00226     case PICK_EDGE:
00227     {
00228       break;
00229     }
00230     case PICK_ANYTHING:
00231     case PICK_FACE:
00232     {
00233       _state.pick_set_maximum (1);
00234       _state.pick_set_name (0);
00235       draw_obj();
00236       break; 
00237     }
00238 
00239     default: // avoid warning
00240       break;
00241   }      
00242 }
00243 
00244 
00245 //----------------------------------------------------------------------------
00246 
00247 
00248 bool 
00249 OBJNode::read(const std::string& _filename)
00250 {
00251   FILE* in = fopen(_filename.c_str(), "r");
00252   if (!in) return false;
00253 
00254 
00255   char                                  s[200];
00256   float                                 x, y, z, u, v;
00257   
00258 
00259   // clear mesh
00260   vertices_.clear();
00261   texCoords_.clear();
00262   faces_.clear();
00263 
00264 
00265 
00266   while(!feof(in) && fgets(s, 200, in))
00267   {
00268     // comment
00269     if (s[0] == '#') continue;
00270 
00271     
00272     // vertex
00273     else if (strncmp(s, "v ", 2) == 0)
00274     {
00275       if (sscanf(s, "v %f %f %f", &x, &y, &z))
00276       {
00277         vertices_.push_back(Vec3f(x,y,z));
00278       }
00279     }
00280 
00281 
00282     // texture coord
00283     else if (strncmp(s, "vt ", 3) == 0)
00284     {
00285       if (sscanf(s, "vt %f %f", &u, &v))
00286         texCoords_.push_back(Vec2f(u, v));
00287     }
00288 
00289     
00290     // face
00291     else if (strncmp(s, "f ", 2) == 0)
00292     {
00293       std::vector<unsigned int>  vIdx, tIdx;
00294       int component(0), nV(0);
00295       bool endOfVertex(false);
00296       char *p0, *p1(s+2);
00297       
00298       vIdx.clear();
00299       tIdx.clear();
00300 
00301     
00302       while(p1)
00303       {
00304         p0 = p1;
00305 
00306         // overwrite next separator
00307         if (p1)
00308         {
00309           while (*p1 != '/' && *p1 != '\r' && *p1 != '\n' && 
00310                  *p1 != ' ' && *p1 != '\0')
00311             p1++;
00312             
00313           // detect end of vertex
00314           if (*p1 != '/') endOfVertex = true;
00315         
00316           // replace separator by '\0'
00317           if (*p1 != '\0') 
00318           {
00319             *p1 = '\0';
00320             p1++; // point to next token
00321           }
00322           
00323           // detect end of line and break
00324           if (*p1 == '\0' || *p1 == '\n')
00325             p1 = 0;
00326         }
00327 
00328         if (*p0 != '\0')
00329         {
00330           switch (component)
00331           {
00332             case 0: vIdx.push_back(atoi(p0)-1); break;
00333             case 1: tIdx.push_back(atoi(p0)-1); break;
00334             case 2: /* ignore vertex normals */ break;
00335           }
00336 
00337           component++;
00338 
00339           if (endOfVertex)
00340           {
00341             component = 0;
00342             nV++;
00343             endOfVertex = false;
00344           }
00345         }
00346       }
00347 
00348       
00349       if (vIdx.size() >= 3)
00350       {
00351         // texture
00352         if (vIdx.size() == tIdx.size())
00353         {
00354           for (unsigned int i1=1, i2=2; i2 < vIdx.size(); ++i1, ++i2)
00355             faces_.push_back(Face(vIdx[0], vIdx[i1], vIdx[i2],
00356                                   tIdx[0], tIdx[i1], tIdx[i2]));
00357         }
00358 
00359         // no texture
00360         else
00361         {
00362           for (unsigned int i1=1, i2=2; i2 < vIdx.size(); ++i1, ++i2)
00363           {
00364             faces_.push_back(Face(vIdx[0], vIdx[i1], vIdx[i2]));
00365           }
00366         }
00367       }
00368     }
00369     
00370 
00371     s[0]=' ';
00372   }
00373 
00374   
00375   fclose(in);
00376 
00377   update_face_normals();
00378 
00379   return true;
00380 }
00381 
00382 
00383 //----------------------------------------------------------------------------
00384 
00385 
00386 void
00387 OBJNode::update_face_normals()
00388 {
00389   normals_.clear();
00390   normals_.reserve(faces_.size());
00391 
00392   std::vector<Face>::const_iterator f_it(faces_.begin()), f_end(faces_.end());
00393   for (; f_it!=f_end; ++f_it)
00394   {
00395     const Vec3f& v0(vertex(f_it->i0));
00396     const Vec3f& v1(vertex(f_it->i1));
00397     const Vec3f& v2(vertex(f_it->i2));
00398     normals_.push_back(((v1-v0) % (v2-v0)).normalize());
00399   }
00400 }
00401 
00402 //=============================================================================
00403 } // namespace SceneGraph
00404 } // namespace ACG
00405 //=============================================================================

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