BALL  1.4.1
surface.h
Go to the documentation of this file.
00001 // -*- Mode: C++; tab-width: 2; -*-
00002 // vi: set ts=2:
00003 //
00004 
00005 #ifndef BALL_MATHS_SURFACE_H
00006 #define BALL_MATHS_SURFACE_H
00007 
00008 #ifndef BALL_MATHS_VECTOR3_H
00009 # include <BALL/MATHS/vector3.h>
00010 #endif
00011 
00012 namespace BALL 
00013 {
00019 
00026   template <typename T>
00027   class TSurface
00028   {
00029     public:
00030 
00031     BALL_CREATE(TSurface)
00032 
00033     
00036 
00039     class Triangle
00040     {
00041       public:
00042         Index v1;
00043         Index v2;
00044         Index v3;
00045 
00046         bool operator == (const Triangle& triangle) const 
00047         {
00048           return (v1 == triangle.v1) && (v2 == triangle.v2) && (v3 == triangle.v3);
00049         }
00050 
00051 
00052         bool operator != (const Triangle& triangle) const 
00053         {
00054           return !(v1 == triangle.v1) && (v2 == triangle.v2) && (v3 == triangle.v3);
00055         }
00056     };
00057       
00059     typedef TVector3<T> Vertex;
00060 
00062     typedef TVector3<T> Normal;
00064 
00068 
00070     TSurface();
00071 
00073     TSurface(const TSurface& surface);
00074 
00076     virtual ~TSurface();
00078 
00082 
00084     void set(const TSurface& surface);
00085 
00087     TSurface& operator = (const TSurface& surface);
00088 
00090     void get(TSurface& surface) const;
00091 
00093     void clear();
00094 
00100     void readMSMSFile(const String& vert_filename, const String& face_filename);
00102 
00106 
00111     float getArea() const;
00112 
00114     Size getNumberOfTriangles() const;
00115     
00117     Size getNumberOfVertices() const;
00118 
00120     Size getNumberOfNormals() const;
00121 
00123     Triangle& getTriangle(Position index);
00124 
00126     const Triangle& getTriangle(Position index) const;
00127       
00129     void clearTriangles();
00130 
00132     void resizeTriangles(Size size);
00133 
00135     void pushBackTriangle(const Triangle& triangle);
00136 
00138     Vertex& getVertex(Position index);
00139 
00141     const Vertex& getVertex(Position index) const;
00142 
00144     void clearVertices();
00145 
00147     void resizeVertices(Size size);
00148 
00150     void pushBackVertex(const Vertex& vertex);
00151 
00153     Normal& getNormal(Position index);
00154 
00156     const Normal& getNormal(Position index) const;
00157 
00159     void clearNormals();
00160 
00162     void resizeNormals(Size size);
00163 
00165     void pushBackNormal(const Normal& n);
00166 
00168 
00172 
00174     bool operator == (const TSurface& surface) const;
00175 
00177     bool operator != (const TSurface& surface) const;
00179 
00183 
00185     vector<Vertex>    vertex;
00186 
00188     vector<Normal>    normal;
00189 
00191     vector<Triangle>  triangle;
00193   };
00195 
00197 #ifdef BALL_COMPILER_MSVC
00198   template class BALL_EXPORT TSurface<float>;
00199 #endif
00200 
00201   template <typename T>
00202   TSurface<T>::TSurface()
00203   {
00204   }
00205 
00206   template <typename T>
00207   TSurface<T>::TSurface(const TSurface<T>& surface)
00208     : vertex(surface.vertex),
00209       normal(surface.normal),
00210       triangle(surface.triangle)
00211   {
00212   }
00213 
00214   template <typename T>
00215   TSurface<T>::~TSurface()
00216   {
00217   }
00218 
00219   template <typename T>
00220   void TSurface<T>::clear()
00221   {
00222     vertex.clear();
00223     normal.clear();
00224     triangle.clear();
00225   }
00226   
00227   template <typename T>
00228   void TSurface<T>::set(const TSurface<T>& surface)
00229   {
00230     vertex = surface.vertex;
00231     normal = surface.normal;
00232     triangle = surface.triangle;
00233   }
00234 
00235   template <typename T>
00236   TSurface<T>& TSurface<T>::operator = (const TSurface<T>& surface)
00237   {
00238     vertex = surface.vertex;
00239     normal = surface.normal;
00240     triangle = surface.triangle;
00241     return *this;
00242   }
00243   
00244   template <typename T>
00245   void TSurface<T>::get(TSurface<T>& surface) const
00246   {
00247     surface.vertex = vertex;
00248     surface.normal = normal;
00249     surface.triangle = triangle;
00250   }
00251   
00252   template <typename T>
00253   void TSurface<T>::readMSMSFile(const String& vert_filename, const String& face_filename)
00254   {
00255     // delete old contents
00256     normal.clear();
00257     vertex.clear();
00258     triangle.clear();
00259 
00260     std::ifstream file(vert_filename.c_str());
00261     if (!file)
00262     {
00263       throw Exception::FileNotFound(__FILE__, __LINE__, vert_filename);
00264     }
00265 
00266     // there are two formats: one with three lines of 
00267     // header and one without
00268     String line;
00269     while ((line.countFields() != 9) && file)
00270     {
00271       line.getline(file);
00272     }
00273     
00274     String s[6];
00275     while (file && (line.countFields() == 9))
00276     {
00277       // read the vertex coordinates and the normal vector 
00278       line.split(s, 6);
00279       vertex.push_back(Vertex(s[0].toFloat(), s[1].toFloat(), s[2].toFloat()));
00280       normal.push_back(Normal(s[3].toFloat(), s[4].toFloat(), s[5].toFloat()));
00281       
00282       // read the next line
00283       line.getline(file);
00284     }
00285     file.close();
00286     // workaround for trouble in File
00287     file.clear();
00288 
00289     // now read the faces file:
00290     file.open(face_filename.c_str());
00291     if (!file)
00292     {
00293       throw Exception::FileNotFound(__FILE__, __LINE__, face_filename);
00294     }
00295 
00296     // there are two formats: one with three lines of 
00297     // header and one without
00298     while ((line.countFields() != 5) && file)
00299     {
00300       line.getline(file);
00301     }
00302     
00303     Triangle t;
00304     Size number_of_vertices = (Size)vertex.size();
00305     while (file && (line.countFields() == 5))
00306     {
00307       // read the vertex indices
00308       line.split(s, 5);
00309       t.v1 = (Index)s[0].toInt() - 1;
00310       t.v2 = (Index)s[1].toInt() - 1;
00311       t.v3 = (Index)s[2].toInt() - 1;
00312 
00313       // if all three vertex indices are valid, insert the triangle
00314       if ((t.v1 < (Index)number_of_vertices) && (t.v1 >= 0)
00315           && (t.v1 < (Index)number_of_vertices) && (t.v1 >= 0)
00316           && (t.v1 < (Index)number_of_vertices) && (t.v1 >= 0))
00317       {
00318         triangle.push_back(t);
00319       }
00320       
00321       // read the next line
00322       line.getline(file);
00323     }
00324     file.close();
00325   }
00326 
00327   template <typename T>
00328   float TSurface<T>::getArea() const
00329   {
00330     // add the areas of all triangles
00331     double area = 0;
00332     for (Size i = 0; i < triangle.size(); i++)
00333     {
00334       // add the length of the vector products of two sides of each triangle
00335       // this is equivalent to the surface area of the parallelogram, and thus to twice the triangle area
00336       area += ((vertex[triangle[i].v2] - vertex[triangle[i].v1]) % (vertex[triangle[i].v3] - vertex[triangle[i].v1])).getLength();
00337     }
00338     
00339     // A = 1/2 \sum |r1 x r2|
00340     return (float)( area * 0.5 );
00341   }
00342 
00343   template <typename T>
00344   bool TSurface<T>::operator == (const TSurface<T>& surface) const
00345   {
00346     return ((surface.vertex == vertex) 
00347             && (surface.normal == normal) 
00348             && (surface.triangle == triangle));
00349   }
00350 
00351   template <typename T>
00352   BALL_INLINE
00353   Size TSurface<T>::getNumberOfTriangles() const
00354   {
00355     return (Size)triangle.size();
00356   }
00357     
00358   template <typename T>
00359   BALL_INLINE
00360   Size TSurface<T>::getNumberOfVertices() const
00361   {
00362     return (Size)vertex.size();
00363   }
00364 
00365   template <typename T>
00366   BALL_INLINE
00367   Size TSurface<T>::getNumberOfNormals() const
00368   {
00369     return (Size)normal.size();
00370   }
00371   
00372   template <typename T>
00373   BALL_INLINE
00374   typename TSurface<T>::Triangle& TSurface<T>::getTriangle(Position index)
00375   {
00376     return triangle[index];
00377   }
00378 
00379   template <typename T>
00380   BALL_INLINE
00381   const typename TSurface<T>::Triangle& TSurface<T>::getTriangle(Position index) const
00382   {
00383     return triangle[index];
00384   }
00385 
00386   template <typename T>
00387   BALL_INLINE
00388   void TSurface<T>::clearTriangles()
00389   {
00390     triangle.clear();
00391   }
00392 
00393   template <typename T>
00394   BALL_INLINE
00395   void TSurface<T>::resizeTriangles(Size size)
00396   {
00397     triangle.resize(size);
00398   }
00399 
00400   template <typename T>
00401   BALL_INLINE
00402   void TSurface<T>::pushBackTriangle(const Triangle& t)
00403   {
00404     triangle.push_back(t);
00405   }
00406 
00407   
00408   template <typename T>
00409   BALL_INLINE
00410   typename TSurface<T>::Vertex& TSurface<T>::getVertex(Position index)
00411   {
00412     return vertex[index];
00413   }
00414 
00415   template <typename T>
00416   BALL_INLINE
00417   const typename TSurface<T>::Vertex& TSurface<T>::getVertex(Position index) const
00418   {
00419     return vertex[index];
00420   }
00421 
00422   template <typename T>
00423   BALL_INLINE
00424   void TSurface<T>::clearVertices()
00425   {
00426     vertex.clear();
00427   }
00428 
00429   template <typename T>
00430   BALL_INLINE
00431   void TSurface<T>::resizeVertices(Size size)
00432   {
00433     vertex.resize(size);
00434   }
00435 
00436   
00437   template <typename T>
00438   BALL_INLINE
00439   void TSurface<T>::pushBackVertex(const typename TSurface<T>::Vertex& position)
00440   {
00441     vertex.push_back(position);
00442   }
00443 
00444   template <typename T>
00445   BALL_INLINE
00446   typename TSurface<T>::Normal& TSurface<T>::getNormal(Position index)
00447   {
00448     return normal[index];
00449   }
00450 
00451   template <typename T>
00452   BALL_INLINE
00453   const typename TSurface<T>::Normal& TSurface<T>::getNormal(Position index) const
00454   {
00455     return normal[index];
00456   }
00457 
00458   template <typename T>
00459   BALL_INLINE
00460   void TSurface<T>::clearNormals()
00461   {
00462     normal.clear();
00463   }
00464 
00465   template <typename T>
00466   BALL_INLINE
00467   void TSurface<T>::resizeNormals(Size size)
00468   {
00469     normal.resize(size);
00470   }
00471 
00472   template <typename T>
00473   BALL_INLINE
00474   void TSurface<T>::pushBackNormal(const typename TSurface<T>::Normal& n)
00475   {
00476     normal.push_back(n);
00477   }
00478 
00479   template <typename T>
00480   bool TSurface<T>::operator != (const TSurface<T>& surface) const
00481   {
00482     return !(*this == surface);
00483   }
00484 
00488   typedef TSurface<float> Surface;
00489 
00490 } // namespace BALL
00491 
00492 #endif // BALL_MATHS_SURFACE_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines