surface.h

Go to the documentation of this file.
00001 // -*- Mode: C++; tab-width: 2; -*-
00002 // vi: set ts=2:
00003 //
00004 // $Id: surface.h,v 1.29 2004/10/22 20:11:54 amoll Exp $
00005 //
00006 
00007 #ifndef BALL_MATHS_SURFACE_H
00008 #define BALL_MATHS_SURFACE_H
00009 
00010 #ifndef BALL_MATHS_VECTOR3_H
00011 # include <BALL/MATHS/vector3.h>
00012 #endif
00013 
00014 namespace BALL 
00015 {
00021 
00028   template <typename T>
00029   class TSurface
00030   {
00031     public:
00032 
00033     BALL_CREATE(TSurface)
00034 
00035     
00038 
00041     class Triangle
00042     {
00043       public:
00044         Index v1;
00045         Index v2;
00046         Index v3;
00047 
00048         bool operator == (const Triangle& triangle) const 
00049         {
00050           return (v1 == triangle.v1) && (v2 == triangle.v2) && (v3 == triangle.v3);
00051         }
00052 
00053 
00054         bool operator != (const Triangle& triangle) const 
00055         {
00056           return !(v1 == triangle.v1) && (v2 == triangle.v2) && (v3 == triangle.v3);
00057         }
00058     };
00059       
00061     typedef TVector3<T> Vertex;
00062 
00064     typedef TVector3<T> Normal;
00066 
00070 
00072     TSurface()
00073       ;
00074 
00076     TSurface(const TSurface& surface)
00077       ;
00078 
00080     virtual ~TSurface()
00081       ;
00083 
00087 
00089     void set(const TSurface& surface)
00090       ;
00091 
00093     TSurface& operator = (const TSurface& surface)
00094       ;
00095 
00097     void get(TSurface& surface) const
00098       ;
00099 
00101     void clear()
00102       ;
00103 
00108     void readMSMSFile(const String& vert_filename, const String& face_filename)
00109       throw(Exception::FileNotFound);
00111 
00115 
00120     float getArea() const
00121       ;
00122 
00124     Size getNumberOfTriangles() const
00125       ;
00126     
00128     Size getNumberOfVertices() const
00129       ;
00130 
00132     Size getNumberOfNormals() const
00133       ;
00134 
00136     Triangle& getTriangle(Position index)
00137       ;
00138 
00140     const Triangle& getTriangle(Position index) const
00141       ;
00142       
00144     void clearTriangles();
00145 
00147     void resizeTriangles(Size size);
00148 
00150     void pushBackTriangle(const Triangle& triangle)
00151       ;
00152 
00154     Vertex& getVertex(Position index)
00155       ;
00156 
00158     const Vertex& getVertex(Position index) const
00159       ;
00160 
00162     void clearVertices();
00163 
00165     void resizeVertices(Size size);
00166 
00168     void pushBackVertex(const Vertex& vertex)
00169       ;
00170 
00172     Normal& getNormal(Position index)
00173       ;
00174 
00176     const Normal& getNormal(Position index) const
00177       ;
00178 
00180     void clearNormals();
00181 
00183     void resizeNormals(Size size);
00184 
00186     void pushBackNormal(const Normal& n)
00187       ;
00188 
00190 
00194 
00196     bool operator == (const TSurface& surface) const
00197       ;
00198 
00200     bool operator != (const TSurface& surface) const
00201       ;
00203 
00207 
00209     vector<Vertex>    vertex;
00210 
00212     vector<Normal>    normal;
00213 
00215     vector<Triangle>  triangle;
00217   };
00219 
00221 #ifdef BALL_COMPILER_MSVC
00222   template class BALL_EXPORT TSurface<float>;
00223 #endif
00224 
00225   template <typename T>
00226   TSurface<T>::TSurface()
00227     
00228   {
00229   }
00230 
00231   template <typename T>
00232   TSurface<T>::TSurface(const TSurface<T>& surface)
00233     
00234     : vertex(surface.vertex),
00235       normal(surface.normal),
00236       triangle(surface.triangle)
00237   {
00238   }
00239 
00240   template <typename T>
00241   TSurface<T>::~TSurface()
00242     
00243   {
00244   }
00245 
00246   template <typename T>
00247   void TSurface<T>::clear()
00248     
00249   {
00250     vertex.clear();
00251     normal.clear();
00252     triangle.clear();
00253   }
00254   
00255   template <typename T>
00256   void TSurface<T>::set(const TSurface<T>& surface)
00257     
00258   {
00259     vertex = surface.vertex;
00260     normal = surface.normal;
00261     triangle = surface.triangle;
00262   }
00263 
00264   template <typename T>
00265   TSurface<T>& TSurface<T>::operator = (const TSurface<T>& surface)
00266     
00267   {
00268     vertex = surface.vertex;
00269     normal = surface.normal;
00270     triangle = surface.triangle;
00271     return *this;
00272   }
00273   
00274   template <typename T>
00275   void TSurface<T>::get(TSurface<T>& surface) const
00276     
00277   {
00278     surface.vertex = vertex;
00279     surface.normal = normal;
00280     surface.triangle = triangle;
00281   }
00282   
00283   template <typename T>
00284   void TSurface<T>::readMSMSFile(const String& vert_filename, const String& face_filename)
00285     throw(Exception::FileNotFound)
00286   {
00287     // delete old contents
00288     normal.clear();
00289     vertex.clear();
00290     triangle.clear();
00291 
00292     std::ifstream file(vert_filename.c_str());
00293     if (!file)
00294     {
00295       throw Exception::FileNotFound(__FILE__, __LINE__, vert_filename);
00296     }
00297 
00298     // there are two formats: one with three lines of 
00299     // header and one without
00300     String line;
00301     while ((line.countFields() != 9) && file)
00302     {
00303       line.getline(file);
00304     }
00305     
00306     String s[6];
00307     while (file && (line.countFields() == 9))
00308     {
00309       // read the vertex coordinates and the normal vector 
00310       line.split(s, 6);
00311       vertex.push_back(Vertex(s[0].toFloat(), s[1].toFloat(), s[2].toFloat()));
00312       normal.push_back(Normal(s[3].toFloat(), s[4].toFloat(), s[5].toFloat()));
00313       
00314       // read the next line
00315       line.getline(file);
00316     }
00317     file.close();
00318     // workaround for trouble in File
00319     file.clear();
00320 
00321     // now read the faces file:
00322     file.open(face_filename.c_str());
00323     if (!file)
00324     {
00325       throw Exception::FileNotFound(__FILE__, __LINE__, face_filename);
00326     }
00327 
00328     // there are two formats: one with three lines of 
00329     // header and one without
00330     while ((line.countFields() != 5) && file)
00331     {
00332       line.getline(file);
00333     }
00334     
00335     Triangle t;
00336     Size number_of_vertices = (Size)vertex.size();
00337     while (file && (line.countFields() == 5))
00338     {
00339       // read the vertex indices
00340       line.split(s, 5);
00341       t.v1 = (Index)s[0].toInt() - 1;
00342       t.v2 = (Index)s[1].toInt() - 1;
00343       t.v3 = (Index)s[2].toInt() - 1;
00344 
00345       // if all three vertex indices are valid, insert the triangle
00346       if ((t.v1 < (Index)number_of_vertices) && (t.v1 >= 0)
00347           && (t.v1 < (Index)number_of_vertices) && (t.v1 >= 0)
00348           && (t.v1 < (Index)number_of_vertices) && (t.v1 >= 0))
00349       {
00350         triangle.push_back(t);
00351       }
00352       
00353       // read the next line
00354       line.getline(file);
00355     }
00356     file.close();
00357   }
00358 
00359   template <typename T>
00360   float TSurface<T>::getArea() const
00361     
00362   {
00363     // add the areas of all triangles
00364     double area = 0;
00365     for (Size i = 0; i < triangle.size(); i++)
00366     {
00367       // add the length of the vector products of two sides of each triangle
00368       // this is equivalent to the surface area of the parallelogram, and thus to twice the triangle area
00369       area += ((vertex[triangle[i].v2] - vertex[triangle[i].v1]) % (vertex[triangle[i].v3] - vertex[triangle[i].v1])).getLength();
00370     }
00371     
00372     // A = 1/2 \sum |r1 x r2|
00373     return (float)( area * 0.5 );
00374   }
00375 
00376   template <typename T>
00377   bool TSurface<T>::operator == (const TSurface<T>& surface) const
00378     
00379   {
00380     return ((surface.vertex == vertex) 
00381             && (surface.normal == normal) 
00382             && (surface.triangle == triangle));
00383   }
00384 
00385   template <typename T>
00386   BALL_INLINE
00387   Size TSurface<T>::getNumberOfTriangles() const
00388       
00389   {
00390     return (Size)triangle.size();
00391   }
00392     
00393   template <typename T>
00394   BALL_INLINE
00395   Size TSurface<T>::getNumberOfVertices() const
00396       
00397   {
00398     return (Size)vertex.size();
00399   }
00400 
00401   template <typename T>
00402   BALL_INLINE
00403   Size TSurface<T>::getNumberOfNormals() const
00404       
00405   {
00406     return (Size)normal.size();
00407   }
00408 
00409   
00410   template <typename T>
00411   BALL_INLINE
00412   typename TSurface<T>::Triangle& TSurface<T>::getTriangle(Position index)
00413     
00414   {
00415     return triangle[index];
00416   }
00417 
00418   template <typename T>
00419   BALL_INLINE
00420   const typename TSurface<T>::Triangle& TSurface<T>::getTriangle(Position index) const
00421     
00422   {
00423     return triangle[index];
00424   }
00425 
00426   
00427   template <typename T>
00428   BALL_INLINE
00429   void TSurface<T>::clearTriangles()
00430   {
00431     triangle.clear();
00432   }
00433 
00434   template <typename T>
00435   BALL_INLINE
00436   void TSurface<T>::resizeTriangles(Size size)
00437   {
00438     triangle.resize(size);
00439   }
00440 
00441   template <typename T>
00442   BALL_INLINE
00443   void TSurface<T>::pushBackTriangle(const Triangle& t)
00444     
00445   {
00446     triangle.push_back(t);
00447   }
00448 
00449   
00450   template <typename T>
00451   BALL_INLINE
00452   typename TSurface<T>::Vertex& TSurface<T>::getVertex(Position index)
00453     
00454   {
00455     return vertex[index];
00456   }
00457 
00458   template <typename T>
00459   BALL_INLINE
00460   const typename TSurface<T>::Vertex& TSurface<T>::getVertex(Position index) const
00461     
00462   {
00463     return vertex[index];
00464   }
00465 
00466   template <typename T>
00467   BALL_INLINE
00468   void TSurface<T>::clearVertices()
00469   {
00470     vertex.clear();
00471   }
00472 
00473   template <typename T>
00474   BALL_INLINE
00475   void TSurface<T>::resizeVertices(Size size)
00476   {
00477     vertex.resize(size);
00478   }
00479 
00480   
00481   template <typename T>
00482   BALL_INLINE
00483   void TSurface<T>::pushBackVertex(const typename TSurface<T>::Vertex& position)
00484     
00485   {
00486     vertex.push_back(position);
00487   }
00488 
00489   template <typename T>
00490   BALL_INLINE
00491   typename TSurface<T>::Normal& TSurface<T>::getNormal(Position index)
00492     
00493   {
00494     return normal[index];
00495   }
00496 
00497   template <typename T>
00498   BALL_INLINE
00499   const typename TSurface<T>::Normal& TSurface<T>::getNormal(Position index) const
00500     
00501   {
00502     return normal[index];
00503   }
00504 
00505   template <typename T>
00506   BALL_INLINE
00507   void TSurface<T>::clearNormals()
00508   {
00509     normal.clear();
00510   }
00511 
00512   template <typename T>
00513   BALL_INLINE
00514   void TSurface<T>::resizeNormals(Size size)
00515   {
00516     normal.resize(size);
00517   }
00518 
00519   template <typename T>
00520   BALL_INLINE
00521   void TSurface<T>::pushBackNormal(const typename TSurface<T>::Normal& n)
00522     
00523   {
00524     normal.push_back(n);
00525   }
00526 
00527   template <typename T>
00528   bool TSurface<T>::operator != (const TSurface<T>& surface) const
00529     
00530   {
00531     return !(*this == surface);
00532   }
00533 
00534 
00538   typedef TSurface<float> Surface;
00539 
00540 } // namespace BALL
00541 
00542 #endif // BALL_MATHS_SURFACE_H