OpenMesh
OpenMesh/Core/IO/importer/ImporterT.hh
00001 /*===========================================================================*\
00002  *                                                                           *
00003  *                               OpenMesh                                    *
00004  *      Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen      *
00005  *                           www.openmesh.org                                *
00006  *                                                                           *
00007  *---------------------------------------------------------------------------* 
00008  *  This file is part of OpenMesh.                                           *
00009  *                                                                           *
00010  *  OpenMesh 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  *  OpenMesh 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 OpenMesh.  If not,                                    *
00031  *  see <http://www.gnu.org/licenses/>.                                      *
00032  *                                                                           *
00033 \*===========================================================================*/ 
00034 
00035 /*===========================================================================*\
00036  *                                                                           *             
00037  *   $Revision: 362 $                                                         *
00038  *   $Date: 2011-01-26 10:21:12 +0100 (Mi, 26 Jan 2011) $                   *
00039  *                                                                           *
00040 \*===========================================================================*/
00041 
00042 
00043 //=============================================================================
00044 //
00045 //  Implements an importer module for arbitrary OpenMesh meshes
00046 //
00047 //=============================================================================
00048 
00049 
00050 #ifndef __IMPORTERT_HH__
00051 #define __IMPORTERT_HH__
00052 
00053 
00054 //=== INCLUDES ================================================================
00055 
00056 
00057 #include <OpenMesh/Core/IO/importer/BaseImporter.hh>
00058 #include <OpenMesh/Core/Utils/vector_cast.hh>
00059 #include <OpenMesh/Core/Utils/color_cast.hh>
00060 #include <OpenMesh/Core/Mesh/Attributes.hh>
00061 #include <OpenMesh/Core/System/omstream.hh>
00062 
00063 
00064 //== NAMESPACES ===============================================================
00065 
00066 
00067 namespace OpenMesh {
00068 namespace IO {
00069 
00070 
00071 //=== IMPLEMENTATION ==========================================================
00072 
00073 
00077 template <class Mesh>
00078 class ImporterT : public BaseImporter
00079 {
00080 public:
00081 
00082   typedef typename Mesh::Point       Point;
00083   typedef typename Mesh::Normal      Normal;
00084   typedef typename Mesh::Color       Color;
00085   typedef typename Mesh::TexCoord2D  TexCoord2D;
00086   typedef std::vector<VertexHandle>  VHandles;
00087 
00088 
00089   ImporterT(Mesh& _mesh) : mesh_(_mesh) {}
00090 
00091 
00092   virtual VertexHandle add_vertex(const Vec3f& _point)
00093   {
00094     return mesh_.add_vertex(vector_cast<Point>(_point));
00095   }
00096 
00097 
00098   virtual FaceHandle add_face(const VHandles& _indices)
00099   {
00100     FaceHandle fh;
00101 
00102     if (_indices.size() > 2)
00103     {
00104       VHandles::const_iterator it, it2, end(_indices.end());
00105 
00106       
00107       // test for valid vertex indices
00108       for (it=_indices.begin(); it!=end; ++it)
00109         if (! mesh_.is_valid_handle(*it))
00110         {
00111           omerr() << "ImporterT: Face contains invalid vertex index\n";
00112           return fh;
00113         }
00114 
00115 
00116       // don't allow double vertices
00117       for (it=_indices.begin(); it!=end; ++it)
00118         for (it2=it+1; it2!=end; ++it2)
00119           if (*it == *it2)
00120           {
00121             omerr() << "ImporterT: Face has equal vertices\n";
00122             failed_faces_.push_back(_indices);
00123             return fh;
00124           }
00125 
00126 
00127       // try to add face
00128       fh = mesh_.add_face(_indices);
00129       if (!fh.is_valid())
00130       {
00131         failed_faces_.push_back(_indices);
00132         return fh;
00133       }
00134     }
00135 
00136     return fh;
00137   }
00138 
00139   // vertex attributes
00140 
00141   virtual void set_normal(VertexHandle _vh, const Vec3f& _normal)
00142   {
00143     if (mesh_.has_vertex_normals())
00144       mesh_.set_normal(_vh, vector_cast<Normal>(_normal));
00145   }
00146 
00147   virtual void set_color(VertexHandle _vh, const Vec4uc& _color)
00148   {
00149     if (mesh_.has_vertex_colors())
00150       mesh_.set_color(_vh, color_cast<Color>(_color));
00151   }
00152 
00153   virtual void set_color(VertexHandle _vh, const Vec3uc& _color)
00154   {
00155     if (mesh_.has_vertex_colors())
00156       mesh_.set_color(_vh, color_cast<Color>(_color));
00157   }
00158 
00159 
00160   virtual void set_texcoord(VertexHandle _vh, const Vec2f& _texcoord)
00161   {
00162     if (mesh_.has_vertex_texcoords2D())
00163       mesh_.set_texcoord2D(_vh, vector_cast<TexCoord2D>(_texcoord));
00164   }
00165 
00166   virtual void set_texcoord(HalfedgeHandle _heh, const Vec2f& _texcoord)
00167   {
00168     if (mesh_.has_halfedge_texcoords2D())
00169       mesh_.set_texcoord2D(_heh, vector_cast<TexCoord2D>(_texcoord));
00170   }
00171 
00172   // edge attributes
00173   
00174   virtual void set_color(EdgeHandle _eh, const Vec4uc& _color)
00175   {
00176       if (mesh_.has_edge_colors())
00177           mesh_.set_color(_eh, color_cast<Color>(_color));
00178   }
00179   
00180   virtual void set_color(EdgeHandle _eh, const Vec3uc& _color)
00181   {
00182       if (mesh_.has_edge_colors())
00183           mesh_.set_color(_eh, color_cast<Color>(_color));
00184   }
00185 
00186   // face attributes
00187 
00188   virtual void set_normal(FaceHandle _fh, const Vec3f& _normal)
00189   {
00190     if (mesh_.has_face_normals())
00191       mesh_.set_normal(_fh, vector_cast<Normal>(_normal));
00192   }
00193 
00194   virtual void set_color(FaceHandle _fh, const Vec3uc& _color)
00195   {
00196     if (mesh_.has_face_colors())
00197       mesh_.set_color(_fh, color_cast<Color>(_color));
00198   }
00199 
00200   virtual void set_color(FaceHandle _fh, const Vec4uc& _color)
00201   {
00202     if (mesh_.has_face_colors())
00203       mesh_.set_color(_fh, color_cast<Color>(_color));
00204   }
00205 
00206   virtual void add_face_texcoords( FaceHandle _fh, VertexHandle _vh, const std::vector<Vec2f>& _face_texcoords)
00207   {
00208     // get first halfedge handle
00209     HalfedgeHandle cur_heh   = mesh_.halfedge_handle(_fh);
00210     HalfedgeHandle end_heh   = mesh_.prev_halfedge_handle(cur_heh);
00211 
00212     // find start heh
00213     while( mesh_.to_vertex_handle(cur_heh) != _vh && cur_heh != end_heh )
00214       cur_heh = mesh_.next_halfedge_handle( cur_heh);
00215 
00216     for(unsigned int i=0; i<_face_texcoords.size(); ++i)
00217     {
00218       set_texcoord( cur_heh, _face_texcoords[i]);
00219       cur_heh = mesh_.next_halfedge_handle( cur_heh);
00220     }
00221   }
00222 
00223   virtual void set_face_texindex( FaceHandle _fh, int _texId ) {
00224     if ( mesh_.has_face_texture_index() ) {
00225       mesh_.set_texture_index(_fh , _texId);
00226     }
00227   }
00228 
00229   virtual void add_texture_information( int _id , std::string _name ) {
00230     OpenMesh::MPropHandleT< std::map< int, std::string > > property;
00231 
00232     if ( !mesh_.get_property_handle(property,"TextureMapping") ) {
00233       mesh_.add_property(property,"TextureMapping");
00234     }
00235 
00236     if ( mesh_.property(property).find( _id ) == mesh_.property(property).end() )
00237       mesh_.property(property)[_id] = _name;
00238   }
00239 
00240   // low-level access to mesh
00241 
00242   virtual BaseKernel* kernel() { return &mesh_; }
00243 
00244   bool is_triangle_mesh() const
00245   { return Mesh::is_triangles(); }
00246 
00247   void reserve(unsigned int nV, unsigned int nE, unsigned int nF)
00248   {
00249     mesh_.reserve(nV, nE, nF);
00250   }
00251 
00252   // query number of faces, vertices, normals, texcoords
00253   size_t n_vertices()  const { return mesh_.n_vertices(); }
00254   size_t n_faces()     const { return mesh_.n_faces(); }
00255   size_t n_edges()     const { return mesh_.n_edges(); }
00256 
00257 
00258   void prepare() { failed_faces_.clear(); }
00259 
00260 
00261   void finish()
00262   {
00263     if (!failed_faces_.empty())
00264     {
00265       omerr() << failed_faces_.size()
00266             << " faces failed, adding them as isolated faces\n";
00267 
00268       for (unsigned int i=0; i<failed_faces_.size(); ++i)
00269       {
00270         VHandles&  vhandles = failed_faces_[i];
00271 
00272         // double vertices
00273         for (unsigned int j=0; j<vhandles.size(); ++j)
00274         {
00275           Point p = mesh_.point(vhandles[j]);
00276           vhandles[j] = mesh_.add_vertex(p);
00277           // DO STORE p, reference may not work since vertex array
00278           // may be relocated after adding a new vertex !
00279           
00280           // Mark vertices of failed face as non-manifold
00281           if (mesh_.has_vertex_status()) {
00282               mesh_.status(vhandles[j]).set_fixed_nonmanifold(true);
00283           }
00284         }
00285 
00286         // add face
00287         FaceHandle fh = mesh_.add_face(vhandles);
00288         
00289         // Mark failed face as non-manifold
00290         if (mesh_.has_face_status())
00291             mesh_.status(fh).set_fixed_nonmanifold(true);
00292         
00293         // Mark edges of failed face as non-two-manifold
00294         if (mesh_.has_edge_status()) {
00295             typename Mesh::FaceEdgeIter fe_it = mesh_.fe_iter(fh);
00296             for(; fe_it; ++fe_it) {
00297                 mesh_.status(fe_it).set_fixed_nonmanifold(true);
00298             }
00299         }
00300       }
00301 
00302       failed_faces_.clear();
00303     }
00304   }
00305 
00306 
00307 
00308 private:
00309 
00310   Mesh& mesh_;
00311   std::vector<VHandles>  failed_faces_;
00312 };
00313 
00314 
00315 //=============================================================================
00316 } // namespace IO
00317 } // namespace OpenMesh
00318 //=============================================================================
00319 #endif
00320 //=============================================================================