00001
00002
00003
00004
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
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
00299
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
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
00315 line.getline(file);
00316 }
00317 file.close();
00318
00319 file.clear();
00320
00321
00322 file.open(face_filename.c_str());
00323 if (!file)
00324 {
00325 throw Exception::FileNotFound(__FILE__, __LINE__, face_filename);
00326 }
00327
00328
00329
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
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
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
00354 line.getline(file);
00355 }
00356 file.close();
00357 }
00358
00359 template <typename T>
00360 float TSurface<T>::getArea() const
00361
00362 {
00363
00364 double area = 0;
00365 for (Size i = 0; i < triangle.size(); i++)
00366 {
00367
00368
00369 area += ((vertex[triangle[i].v2] - vertex[triangle[i].v1]) % (vertex[triangle[i].v3] - vertex[triangle[i].v1])).getLength();
00370 }
00371
00372
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 }
00541
00542 #endif // BALL_MATHS_SURFACE_H