MechSys  1.0
Computing library for simulations in continuum and discrete mechanics
/home/dorival/mechsys/lib/mesh/alphashape.h
Go to the documentation of this file.
00001 /************************************************************************
00002  * MechSys - Open Library for Mechanical Systems                        *
00003  * Copyright (C) 2005 Dorival M. Pedroso, Raul Durand                   *
00004  * Copyright (C) 2009 Sergio Galindo                                    *
00005  *                                                                      *
00006  * This program is free software: you can redistribute it and/or modify *
00007  * it under the terms of the GNU General Public License as published by *
00008  * the Free Software Foundation, either version 3 of the License, or    *
00009  * any later version.                                                   *
00010  *                                                                      *
00011  * This program is distributed in the hope that it will be useful,      *
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of       *
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the         *
00014  * GNU General Public License for more details.                         *
00015  *                                                                      *
00016  * You should have received a copy of the GNU General Public License    *
00017  * along with this program. If not, see <http://www.gnu.org/licenses/>  *
00018  ************************************************************************/
00019 
00020 #ifndef MECHSYS_MESH_ALPHASHAPE_H
00021 #define MECHSYS_MESH_ALPHASHAPE_H
00022 
00023 // STL
00024 #include <list>
00025 #include <map>
00026 
00027 // CGAL
00028 #include <CGAL/Alpha_shape_2.h>
00029 #include <CGAL/Alpha_shape_3.h>
00030 #include <CGAL/Delaunay_triangulation_2.h>
00031 #include <CGAL/Delaunay_triangulation_3.h>
00032 #include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
00033 
00034 // MechSys
00035 #include <mechsys/util/array.h>
00036 #include <mechsys/util/fatal.h>
00037 #include <mechsys/mesh/mesh.h>
00038 
00039 namespace Mesh
00040 {
00041 
00042 typedef CGAL::Exact_predicates_inexact_constructions_kernel                      CGAL_K;
00043 typedef CGAL::Alpha_shape_vertex_base_2<CGAL_K>                                  CGAL_VB_2;
00044 typedef CGAL::Triangulation_face_base_2<CGAL_K>                                  CGAL_TF_2;
00045 typedef CGAL::Alpha_shape_face_base_2<CGAL_K,CGAL_TF_2>                          CGAL_FB_2;
00046 typedef CGAL::Triangulation_default_data_structure_2<CGAL_K,CGAL_VB_2,CGAL_FB_2> CGAL_TDS_2;
00047 typedef CGAL::Delaunay_triangulation_2<CGAL_K,CGAL_TDS_2>                        CGAL_DT_2;
00048 typedef CGAL::Alpha_shape_2<CGAL_DT_2>                                           CGAL_ALPHA_SHAPE_2;
00049 typedef CGAL::Alpha_shape_vertex_base_3<CGAL_K>                                  CGAL_VB_3;
00050 typedef CGAL::Alpha_shape_cell_base_3<CGAL_K>                                    CGAL_FB_3;
00051 typedef CGAL::Triangulation_data_structure_3<CGAL_VB_3,CGAL_FB_3>                CGAL_TDS_3;
00052 typedef CGAL::Delaunay_triangulation_3<CGAL_K,CGAL_TDS_3>                        CGAL_DT_3;
00053 typedef CGAL::Alpha_shape_3<CGAL_DT_3>                                           CGAL_ALPHA_SHAPE_3;
00054 
00055 class AlphaShape : public virtual Mesh::Generic
00056 {
00057 public:
00058     // Constructor
00059     AlphaShape (int NDim) : Mesh::Generic(NDim) {}
00060 
00061     // Methods
00062     void ResetCloud    ();                                    
00063     void AddCloudPoint (double X, double Y, double Z=0);      
00064     void Generate      (double Alpha=-1, bool Regular=false); 
00065 
00066 private:
00067     // Data
00068     std::list<CGAL_K::Point_2> _pts_2d; 
00069     std::list<CGAL_K::Point_3> _pts_3d; 
00070 };
00071 
00072 
00074 
00075 
00076 inline void AlphaShape::ResetCloud ()
00077 {
00078     _pts_2d.clear();
00079     _pts_3d.clear();
00080 }
00081 
00082 inline void AlphaShape::AddCloudPoint (double X, double Y, double Z)
00083 {
00084     if (NDim==3) _pts_3d.push_back (CGAL_K::Point_3(X,Y,Z));
00085     else         _pts_2d.push_back (CGAL_K::Point_2(X,Y));
00086 }
00087 
00088 inline void AlphaShape::Generate (double Alpha, bool Regular)
00089 {
00090     if (NDim==3)
00091     {
00092         // Alpha-shape structure
00093         CGAL_ALPHA_SHAPE_3 as(_pts_3d.begin(), _pts_3d.end(), /*alpha*/0, (Regular ? CGAL_ALPHA_SHAPE_3::REGULARIZED : CGAL_ALPHA_SHAPE_3::GENERAL));
00094 
00095         // Find optimal alpha
00096         double alp = Alpha;
00097         if (alp<0) alp = (*as.find_optimal_alpha(1));
00098 
00099         // Generate alpha shape
00100         as.set_alpha (alp);
00101         if (as.number_of_solid_components()!=1) throw new Fatal("AlphaShape::Generate: There is a problem with AlphaShape 3D");
00102     }
00103     else
00104     {
00105         // Alpha-shape structure
00106         CGAL_ALPHA_SHAPE_2 as(_pts_2d.begin(), _pts_2d.end(), /*alpha*/0, (Regular ? CGAL_ALPHA_SHAPE_2::REGULARIZED : CGAL_ALPHA_SHAPE_2::GENERAL));
00107 
00108         // Find optimal alpha
00109         double alp = Alpha;
00110         if (alp<0) alp = (*as.find_optimal_alpha(1));
00111 
00112         // Generate alpha shape
00113         as.set_alpha (alp);
00114 
00115         // Erase old mesh
00116         Erase ();
00117 
00118         // Set Vertices
00119         size_t id = 0;
00120         std::map<CGAL_ALPHA_SHAPE_2::Vertex_handle,size_t> vs;
00121         for (CGAL_ALPHA_SHAPE_2::Alpha_shape_vertices_iterator it=as.alpha_shape_vertices_begin(); it!=as.alpha_shape_vertices_end(); ++it)
00122         {
00123             PushVert (-100, (*it)->point().x(), (*it)->point().y());
00124             vs[(*it)] = id++;
00125         }
00126 
00127         // Set Elements
00128         for (CGAL_ALPHA_SHAPE_2::Alpha_shape_edges_iterator it=as.alpha_shape_edges_begin(); it!=as.alpha_shape_edges_end(); ++it)
00129         {
00130             PushCell (-1, Array<int>((int)vs[it->first->vertex(as.ccw(it->second))], (int)vs[it->first->vertex(as.cw(it->second))]));
00131         }
00132     }
00133 }
00134 
00135 }; // namespace Mesh
00136 
00137 
00138 #endif // MECHSYS_MESH_ALPHASHAPE_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines