![]() |
MechSys
1.0
Computing library for simulations in continuum and discrete mechanics
|
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