trimesh.cpp

Go to the documentation of this file.
00001 /*
00002  * trimesh.cpp
00003  *
00004  * Copyright (c) 2009 Thomas A. Vaughan
00005  * All rights reserved.
00006  *
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions are met:
00010  *     * Redistributions of source code must retain the above copyright
00011  *       notice, this list of conditions and the following disclaimer.
00012  *     * Redistributions in binary form must reproduce the above copyright
00013  *       notice, this list of conditions and the following disclaimer in the
00014  *       documentation and/or other materials provided with the distribution.
00015  *     * Neither the name of the <organization> nor the
00016  *       names of its contributors may be used to endorse or promote products
00017  *       derived from this software without specific prior written permission.
00018  *
00019  * THIS SOFTWARE IS PROVIDED BY THOMAS A. VAUGHAN ''AS IS'' AND ANY
00020  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00021  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00022  * DISCLAIMED. IN NO EVENT SHALL THOMAS A. VAUGHAN BE LIABLE FOR ANY
00023  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00024  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00025  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00026  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00027  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00028  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00029  *
00030  * Support for triangle meshes.  See trimesh.h
00031  */
00032 
00033 // includes --------------------------------------------------------------------
00034 #include "trimesh.h"            // always include our own header first
00035 
00036 #include <fstream>
00037 
00038 #include "common/wave_ex.h"
00039 #include "perf/perf.h"
00040 #include "util/token_stream.h"
00041 
00042 
00043 namespace trimesh {
00044 
00045 /// \ingroup trimesh
00046 /*@{*/
00047 
00048 
00049 // interface destructors
00050 Trimesh::~Trimesh(void) throw() { }
00051 
00052 
00053 
00054 ////////////////////////////////////////////////////////////////////////////////
00055 //
00056 //      static helper methods
00057 //
00058 ////////////////////////////////////////////////////////////////////////////////
00059 
00060 
00061 ////////////////////////////////////////////////////////////////////////////////
00062 //
00063 //      Mesh -- class that implements the Trimesh interface
00064 //
00065 ////////////////////////////////////////////////////////////////////////////////
00066 
00067 class Mesh : public Trimesh {
00068 public:
00069         // constructor, destructor ---------------------------------------------
00070         Mesh(void) throw();
00071         ~Mesh(void) throw();
00072 
00073         // public class methods ------------------------------------------------
00074         void initialize(IN const char * filename);
00075 
00076         // trimesh::Trimesh class interface methods ----------------------------
00077         int getVertexCount(void) const throw() { return m_nVertices; }
00078         int getTriangleCount(void) const throw() { return m_nTriangles; }
00079         const point3d_t * getVertexArray(void) const throw() { return m_vertices; }
00080         const int * getTriangleArray(void) const throw() { return m_triangles; }
00081         void dump(IN const char * title) const throw();
00082 
00083 private:
00084         // private member data -------------------------------------------------
00085         int             m_nVertices;
00086         int             m_nTriangles;
00087         point3d_t *     m_vertices;
00088         int *           m_triangles;
00089 };
00090 
00091 
00092 
00093 Mesh::Mesh(void)
00094 throw()
00095 {
00096         m_nVertices = m_nTriangles = 0;
00097         m_vertices = NULL;
00098         m_triangles = NULL;
00099 }
00100 
00101 
00102 Mesh::~Mesh(void)
00103 throw()
00104 {
00105         if (m_vertices) {
00106                 delete[] m_vertices;
00107         }
00108         if (m_triangles) {
00109                 delete[] m_triangles;
00110         }
00111 }
00112 
00113 
00114 
00115 void
00116 Mesh::initialize
00117 (
00118 IN const char * filename
00119 )
00120 {
00121         ASSERT(filename, "null");
00122 
00123         // open file
00124         std::ifstream infile(filename);
00125         if (!infile.good()) {
00126                 WAVE_EX(wex);
00127                 wex << "Could not open triangle mesh file: " << filename;
00128         }
00129         std::string token;
00130 
00131         // get vertex count and allocate memory
00132         expectToken(infile, "nVertices");
00133         m_nVertices = readInteger(infile, token);
00134         if (m_nVertices < 0) {
00135                 WAVE_EX(wex);
00136                 wex << "Invalid vertex count (" << m_nVertices << ") in ";
00137                 wex << filename;
00138         }
00139 
00140         m_vertices = new point3d_t[m_nVertices];
00141         ASSERT(m_vertices, "out of memory");
00142 
00143         // read vertices
00144         for (int i = 0; i < m_nVertices; ++i) {
00145                 expectToken(infile, "v");
00146                 point3d_t& p = m_vertices[i];
00147 
00148                 // read x,y,z coordinates for this vertex
00149                 p.x = readFloat(infile, token);
00150                 p.y = readFloat(infile, token);
00151                 p.z = readFloat(infile, token);
00152         }
00153 
00154         // get triangle count and allocate memory
00155         expectToken(infile, "nTriangles");
00156         m_nTriangles = readInteger(infile, token);
00157         if (m_nTriangles < 0) {
00158                 WAVE_EX(wex);
00159                 wex << "Invalid triangle count (" << m_nTriangles << ") in ";
00160                 wex << filename;
00161         }
00162         m_triangles = new int[3 * m_nTriangles];
00163         ASSERT(m_triangles, "out of memory");
00164 
00165         // read triangles
00166         for (int i = 0; i < m_nTriangles; ++i) {
00167                 expectToken(infile, "t");
00168                 int * index = m_triangles + (3 * i);
00169 
00170                 // read the 3 vertex indices for this triangle
00171                 index[0] = readInteger(infile, token);
00172                 index[1] = readInteger(infile, token);
00173                 index[2] = readInteger(infile, token);
00174         }
00175 }
00176 
00177 
00178 
00179 void
00180 Mesh::dump
00181 (
00182 IN const char * title
00183 )
00184 const
00185 throw()
00186 {
00187         ASSERT(title, "null");
00188 
00189         DPRINTF("Triangle mesh: %s", title);
00190         DPRINTF("  vertex count:   %4d", m_nVertices);
00191         DPRINTF("  triangle count: %4d", m_nTriangles);
00192 }
00193 
00194 
00195 
00196 ////////////////////////////////////////////////////////////////////////////////
00197 //
00198 //      Public APIs
00199 //
00200 ////////////////////////////////////////////////////////////////////////////////
00201 
00202 smart_ptr<Trimesh>
00203 Trimesh::load
00204 (
00205 IN const char * filename
00206 )
00207 {
00208         perf::Timer timer("TriangleMesh::load");
00209         ASSERT(filename, "null");
00210 
00211         smart_ptr<Mesh> local = new Mesh;
00212         ASSERT(local, "out of memory");
00213 
00214         local->initialize(filename);
00215 
00216         return local;
00217 }
00218 
00219 
00220 
00221 };      // trimesh namespace
00222