00001
00002
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
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
00267
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
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
00283 line.getline(file);
00284 }
00285 file.close();
00286
00287 file.clear();
00288
00289
00290 file.open(face_filename.c_str());
00291 if (!file)
00292 {
00293 throw Exception::FileNotFound(__FILE__, __LINE__, face_filename);
00294 }
00295
00296
00297
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
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
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
00322 line.getline(file);
00323 }
00324 file.close();
00325 }
00326
00327 template <typename T>
00328 float TSurface<T>::getArea() const
00329 {
00330
00331 double area = 0;
00332 for (Size i = 0; i < triangle.size(); i++)
00333 {
00334
00335
00336 area += ((vertex[triangle[i].v2] - vertex[triangle[i].v1]) % (vertex[triangle[i].v3] - vertex[triangle[i].v1])).getLength();
00337 }
00338
00339
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 }
00491
00492 #endif // BALL_MATHS_SURFACE_H