Mesh.hpp
00001 //
00002 // SAL3D Mesh Class
00003 // Copyright 2010 AQSENSE, S.L.
00004 //
00005 
00006 #ifndef AQSENSE_SAL3DPP_MESH_HPP
00007 #define AQSENSE_SAL3DPP_MESH_HPP
00008 
00009 #include <stdio.h>
00010 #include <cassert>
00011 #include <string>
00012 #include <stdexcept>
00013 #include <sal3d/mesh.h>
00014 #include <sal3d/sal3d_def.h>
00015 #include <sal3dpp/COP.hpp>
00016 #include <sal3dpp/Common.hpp>
00017 
00018 namespace sal3d
00019 {
00039     // TODO: points not belonging to mesh?
00040     class Mesh
00041     {
00042         public:
00044             typedef sal3d_mesh_triangle Triangle;
00046             typedef sal3d_mesh_vertex Vertex;
00047 
00049             typedef Array1D<Triangle> Triangles;
00051             typedef Array1D<Vertex> Vertices;
00052 
00069             static Mesh MeshFromPLY(const std::string &filename)
00070             {
00071                 sal3d_mesh mesh;
00072                 mesh.p = 0;
00073                 Error e;
00074                 sal3d_mesh_new_from_ply(&mesh, filename.c_str(), &e.e);
00075                 if (e.e.value < 0)
00076                     throw e;
00077 
00078                 return Mesh(mesh);
00079             }
00080 
00097             static Mesh MeshFromSTL(const std::string &filename)
00098             {
00099                 sal3d_mesh mesh;
00100                 mesh.p = 0;
00101                 Error e;
00102                 sal3d_mesh_new_from_stl(&mesh, filename.c_str(), &e.e);
00103                 if (e.e.value < 0)
00104                     throw e;
00105 
00106                 return Mesh(mesh);
00107             }
00108 
00115             Mesh(int numVertices = 0, int numTriangles = 0)
00116             {
00117                 _mesh.p  = 0;
00118                 Error e;
00119                 sal3d_mesh_new_empty_mesh(&_mesh, numVertices,
00120                         numTriangles, &e.e);
00121                 if (e.e.value < 0)
00122                     throw e;
00123             }
00124 
00131             Mesh(const sal3d::COP &cop)
00132             {
00133                 Error e;
00134                 sal3d_mesh_new_from_cop(cop.c_cop(), &_mesh, &e.e);
00135                 if (e.e.value < 0)
00136                     throw e;
00137             }
00138 
00144             Mesh(const Mesh &mesh):
00145                 _mesh(mesh._mesh)
00146             {
00147                 Error e;
00148                 sal3d_mesh_share(_mesh, &e.e);
00149                 if (e.e.value < 0)
00150                     throw e;
00151             }
00152 
00166             explicit Mesh(sal3d_mesh mesh):
00167                 _mesh(mesh)
00168             {
00169                 Error e;
00170                 sal3d_mesh_is_valid(mesh, &e.e);
00171                 if (e.e.value < 0)
00172                     throw e;
00173             }
00174 
00184             Mesh(const Mesh &mesh, const Movement3D &movement)
00185             {
00186                 _mesh.p = 0;
00187                 Error e;
00188                 sal3d_mesh_new_from_moved (mesh.c_mesh (),
00189                        movement.c_movement_3d (), &_mesh, &e.e);
00190                 if (e.e.value < 0)
00191                     throw e;
00192             }
00193 
00200             ~Mesh()
00201             {
00202                 sal3d_mesh_release(_mesh);
00203             }
00204 
00211             void
00212             clear()
00213             {
00214                 Error e;
00215                 sal3d_mesh_clear(_mesh, &e.e);
00216                 if (e.e.value < 0)
00217                     throw e;
00218             }
00219 
00225             bool
00226             isEmpty()
00227             {
00228                 return (getNumTriangles() == 0 && getNumVertices() == 0);
00229             }
00230 
00237             void
00238             mergeMesh(const Mesh &mesh)
00239             {
00240                 addTriangles(mesh.getVertices(), mesh.getTriangles());
00241             }
00242 
00250             int
00251             getNumTriangles() const
00252             {
00253                 Error e;
00254                 int numTriangles =
00255                     sal3d_mesh_num_triangles(_mesh, &e.e);
00256                 if (e.e.value < 0)
00257                     throw e;
00258 
00259                 return numTriangles;
00260             }
00261 
00269             int
00270             getNumVertices() const
00271             {
00272                 Error e;
00273                 int numVertices =
00274                     sal3d_mesh_num_vertices(_mesh, &e.e);
00275                 if (e.e.value < 0)
00276                     throw e;
00277 
00278                 return numVertices;
00279             }
00280 
00289             void
00290             addTriangles(const std::vector<Vertex> &vertices, const
00291                     std::vector<Triangle> &triangles)
00292             {
00293                 Error e;
00294                 sal3d_mesh_add_triangles(_mesh, &vertices[0],
00295                         static_cast<int>(vertices.size()),
00296                         &triangles[0], static_cast<int>(triangles.size()),
00297                         &e.e);
00298                 if (e.e.value < 0)
00299                     throw e;
00300             }
00301 
00310             void
00311             addTriangles(const Vertices &vertices,
00312                     const Triangles &triangles)
00313             {
00314                 Error e;
00315                 sal3d_mesh_add_triangles(_mesh, &vertices[0],
00316                         vertices.length(), &triangles[0], triangles.length(),
00317                         &e.e);
00318                 if (e.e.value < 0)
00319                     throw e;
00320             }
00321 
00329             const Triangles
00330             getTriangles() const
00331             {
00332                 sal3d_mesh_triangle *triangles = 0;
00333                 Error e;
00334                 sal3d_mesh_get_triangles(_mesh, &triangles,
00335                         &e.e);
00336                 if (e.e.value < 0)
00337                     throw e;
00338 
00339                 return Triangles(triangles, getNumTriangles());
00340             }
00341 
00349             Triangles
00350             getTriangles()
00351             {
00352                 return static_cast<const Mesh &> (*this).getTriangles ();
00353             }
00354 
00362             const Vertices
00363             getVertices() const
00364             {
00365                 sal3d_mesh_vertex *values = 0;
00366                 Error e;
00367                 sal3d_mesh_get_vertices(_mesh, &values,
00368                         &e.e);
00369                 if (e.e.value < 0)
00370                     throw e;
00371 
00372                 return Vertices(values, getNumVertices());
00373             }
00374 
00382             Vertices
00383             getVertices()
00384             {
00385                 return static_cast<const Mesh &> (*this).getVertices ();
00386             }
00387 
00395             void
00396             exportToBinaryPLY(const std::string &filename) const
00397             {
00398                 Error e;
00399                 sal3d_mesh_export_bin_ply(_mesh,
00400                         filename.c_str(), &e.e);
00401                 if (e.e.value < 0)
00402                     throw e;
00403             }
00404 
00412             void
00413             exportToASCIIPLY(const std::string &filename) const
00414             {
00415                 Error e;
00416                 sal3d_mesh_export_ascii_ply(_mesh,
00417                         filename.c_str(), &e.e);
00418                 if (e.e.value < 0)
00419                     throw e;
00420             }
00421 
00431             void
00432             exportToBinarySTL(const std::string &filename,
00433                     const std::string &header = std::string("")) const
00434             {
00435                 Error e;
00436                 sal3d_mesh_export_bin_stl(_mesh,
00437                         filename.c_str(), header.c_str(),
00438                         &e.e);
00439                 if (e.e.value < 0)
00440                     throw e;
00441             }
00442 
00450             void
00451             exportToASCIISTL(const std::string &filename) const
00452             {
00453                 Error e;
00454                 sal3d_mesh_export_ascii_stl(_mesh,
00455                         filename.c_str(),
00456                         &e.e);
00457                 if (e.e.value < 0)
00458                     throw e;
00459             }
00460 
00468             Mesh &
00469             operator= (const Mesh &aMesh)
00470             {
00471                 Error e;
00472                 sal3d_mesh_share (aMesh._mesh, &e.e);
00473                 if (e.e.value < 0)
00474                     throw e;
00475                 sal3d_mesh_release (_mesh);
00476                 _mesh = aMesh._mesh;
00477 
00478                 return *this;
00479             }
00480 
00490             sal3d_mesh
00491             c_mesh() const
00492             {
00493                 return _mesh;
00494             }
00495 
00501             void
00502             glPaintPoints() const
00503             {
00504                 Error e;
00505                 sal3d_mesh_gl_paint_points(_mesh,
00506                         &e.e);
00507                 if (e.e.value < 0)
00508                     throw e;
00509             }
00510 
00520             void
00521             glPaintRandomPoints(int num_points) const
00522             {
00523                 Error e;
00524                 sal3d_mesh_gl_paint_random_points(_mesh,
00525                         num_points,
00526                         &e.e);
00527                 if (e.e.value < 0)
00528                     throw e;
00529             }
00530 
00536             void
00537             glPaintPolygons() const
00538             {
00539                 Error e;
00540                 sal3d_mesh_gl_paint_polygons(_mesh, &e.e);
00541                 if (e.e.value < 0)
00542                     throw e;
00543             }
00544 
00555             Mesh
00556             copy() const
00557             {
00558                 sal3d_mesh mesh;
00559                 Error e;
00560                 sal3d_mesh_duplicate(_mesh, &mesh, &e.e);
00561                 if (e.e.value < 0)
00562                     throw e;
00563                 return Mesh(mesh);
00564             }
00565 
00584             void
00585             cropGL (const Projection2D &projection, const Polygon2D &polygon2d,
00586                     bool keepInsidePoints = true)
00587             {
00588                 std::vector<Projection2D> projection_vec (1, projection);
00589                 std::vector<Polygon2D> polygon_vec (1, polygon2d);
00590 
00591                 cropGL (projection_vec, polygon_vec, keepInsidePoints);
00592             }
00593 
00612             void
00613             cropGL (const std::vector<Projection2D> &projections, const
00614                     std::vector<Polygon2D> &polygons, bool keepInsidePoints = true)
00615             {
00616                 std::vector<sal3d_polygon2d> c_polygons (polygons.size ());
00617 
00618                 for (unsigned int i = 0; i < projections.size (); ++i)
00619                 {
00620                     c_polygons[i] = polygons[i].c_polygon_2d ();
00621                 }
00622 
00623                 Error e;
00624                 sal3d_mesh_crop_polygons_gl (_mesh,
00625                         &projections[0], &c_polygons[0],static_cast<int> (
00626                             projections.size ()), static_cast<int>
00627                             (keepInsidePoints), &e.e);
00628                 if (e.e.value < 0)
00629                     throw e;
00630             }
00631 
00632         private:
00634             sal3d_mesh _mesh;
00635     };
00636 }
00637 
00638 #endif