BWAPI
|
00001 // Copyright (c) 2003-2006 INRIA Sophia-Antipolis (France). 00002 // All rights reserved. 00003 // 00004 // This file is part of CGAL (www.cgal.org); you may redistribute it under 00005 // the terms of the Q Public License version 1.0. 00006 // See the file LICENSE.QPL distributed with CGAL. 00007 // 00008 // Licensees holding a valid commercial license may use this file in 00009 // accordance with the commercial license agreement provided with the software. 00010 // 00011 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 00012 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 00013 // 00014 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Surface_mesher/include/CGAL/Surface_mesher/Standard_criteria.h $ 00015 // $Id: Standard_criteria.h 43499 2008-06-06 12:28:14Z lrineau $ 00016 // 00017 // 00018 // Author(s) : Steve OUDOT, Laurent Rineau 00019 00020 00021 #ifndef CGAL_SURFACE_MESHER_STANDARD_CRITERIA_H 00022 #define CGAL_SURFACE_MESHER_STANDARD_CRITERIA_H 00023 00024 #include <cmath> 00025 #include <vector> 00026 00027 00028 namespace CGAL { 00029 00030 namespace Surface_mesher { 00031 00032 00033 template <class Criterion> 00034 class Standard_criteria { 00035 00036 protected: 00037 typedef typename Criterion::Quality FT; 00038 typedef std::vector<Criterion*> Criteria; 00039 Criteria criteria; 00040 00041 public: 00042 typedef typename Criterion::Facet Facet; 00043 typedef std::vector<FT> Quality; 00044 00045 Standard_criteria() {} 00046 00047 Standard_criteria (const Criteria& c) : criteria (c) {} 00048 00049 void set_criteria(const Criteria& c) 00050 { 00051 criteria = c; 00052 } 00053 00054 bool is_bad (const Facet& f, Quality& q ) const { 00055 #ifdef CGAL_SURFACE_MESHER_DEBUG_CRITERIA 00056 bool bad = false; 00057 #endif 00058 int i = 0; 00059 q.resize(criteria.size()); 00060 for (typename Criteria::const_iterator cit = criteria.begin(); cit != 00061 criteria.end(); ++cit) 00062 if ((*cit)->is_bad (f, q[i++])) 00063 #ifndef CGAL_SURFACE_MESHER_DEBUG_CRITERIA 00064 return true; 00065 return false; 00066 #else 00067 bad = true; 00068 if( bad ) 00069 { 00070 std::cerr << "bad triangle: |"; 00071 for(typename Criteria::iterator cit = criteria.begin(); cit != 00072 criteria.end(); ++cit) 00073 { 00074 FT dummy_q; 00075 std::cerr << (*cit)->is_bad (f, dummy_q) << "|" ; 00076 } 00077 std::cerr << "\n"; 00078 } 00079 return bad; 00080 #endif 00081 } 00082 }; 00083 00084 // abstract basic Criterion class 00085 template <class Tr> 00086 class Refine_criterion { 00087 public: 00088 typedef typename Tr::Facet Facet; 00089 typedef typename Tr::Geom_traits::FT Quality; 00090 virtual bool is_bad (const Facet&, Quality& ) const = 0; 00091 virtual ~Refine_criterion() {} 00092 }; 00093 00094 // Aspect_ratio Criterion class 00095 template <class Tr> 00096 class Aspect_ratio_criterion : public Refine_criterion <Tr> { 00097 public: 00098 typedef typename Refine_criterion <Tr>::Quality Quality; 00099 typedef typename Tr::Geom_traits::FT FT; 00100 00101 private: 00102 typedef typename Refine_criterion <Tr>::Facet Facet; 00103 typedef typename Tr::Point Point; 00104 00105 Quality B; 00106 00107 public: 00108 // Nb: the default bound of the criterion is such that the criterion 00109 // is always fulfilled 00110 Aspect_ratio_criterion(const FT angle_min = 0.) 00111 { // TODO: document that FT must constructible from a double! 00112 set_angle_min(angle_min); 00113 } 00114 00115 inline 00116 Quality bound() const { return B; } 00117 00118 inline 00119 Quality angle_min() const { return std::asin (std::sqrt(B)); } 00120 00121 inline 00122 void set_bound(const Quality b) { B = b; }; 00123 00124 inline 00125 void set_angle_min(const FT angle_min) { 00126 if(angle_min == FT(0)) { 00127 B = 0; 00128 } 00129 else { 00130 B = std::sin (CGAL_PI * CGAL::to_double(angle_min) / 180); 00131 B = B * B; 00132 } 00133 }; 00134 00135 bool is_bad (const Facet& fh, Quality& q) const { 00136 CGAL_assertion (fh.first->is_facet_on_surface (fh.second)); 00137 00138 if(B == FT(0)) { 00139 q = 1; 00140 return false; 00141 } 00142 00143 typedef typename Tr::Geom_traits Geom_traits; 00144 Geom_traits gt; 00145 typename Geom_traits::Triangle_3 t; 00146 00147 Point p1 = fh.first->vertex ((fh.second+1)&3)->point(); 00148 Point p2 = fh.first->vertex ((fh.second+2)&3)->point(); 00149 Point p3 = fh.first->vertex ((fh.second+3)&3)->point(); 00150 t = gt.construct_triangle_3_object()(p1,p2,p3); 00151 00152 Quality d12,d13,d23; 00153 d12=gt.compute_squared_distance_3_object()(p1,p2); 00154 d13=gt.compute_squared_distance_3_object()(p1,p3); 00155 d23=gt.compute_squared_distance_3_object()(p2,p3); 00156 00157 Quality aspect_ratio = 4 * gt.compute_squared_area_3_object()(t) 00158 * min_3(d12,d13,d23) / (d12*d13*d23); 00159 00160 CGAL_assertion (aspect_ratio >= 0 && aspect_ratio <= 1); 00161 q = aspect_ratio; 00162 return (B == FT(0)) || (aspect_ratio < B); 00163 } 00164 00165 private: 00166 static 00167 Quality min_3 (const Quality a, const Quality b, const Quality c) { 00168 if (a<=b && a<=c) 00169 return(a); 00170 00171 else if (b<=c) 00172 return(b); 00173 00174 else 00175 return(c); 00176 } 00177 }; // end Aspect_ratio_criterion 00178 00179 // Curvature_adapted size Criterion class 00180 template <class Tr> 00181 class Curvature_size_criterion : public Refine_criterion <Tr> { 00182 public: 00183 typedef typename Refine_criterion <Tr>::Quality Quality; 00184 00185 private: 00186 typedef typename Refine_criterion <Tr>::Facet Facet; 00187 typedef typename Tr::Point Point; 00188 00189 Quality B; 00190 00191 public: 00192 // Nb: the default bound of the criterion is such that the criterion 00193 // is always fulfilled 00194 Curvature_size_criterion(const Quality b = 1000) : B(b * b) {} 00195 00196 inline 00197 Quality bound() const { return std::sqrt (B); } 00198 00199 inline 00200 void set_bound(const Quality b) { B = b * b; }; 00201 00202 00203 bool is_bad (const Facet& fh, Quality& q) const { 00204 CGAL_assertion (fh.first->is_facet_on_surface (fh.second)); 00205 00206 if(B == Quality(0)) { 00207 q = 1; 00208 return false; 00209 } 00210 00211 typedef typename Tr::Geom_traits Geom_traits; 00212 typedef typename Geom_traits::FT FT; 00213 00214 Geom_traits gt; 00215 typename Geom_traits::Compute_squared_distance_3 distance = 00216 gt.compute_squared_distance_3_object(); 00217 00218 const Point& p1 = fh.first->vertex ((fh.second+1)&3)->point(); 00219 const Point& p2 = fh.first->vertex ((fh.second+2)&3)->point(); 00220 const Point& p3 = fh.first->vertex ((fh.second+3)&3)->point(); 00221 00222 const Point c = gt.construct_circumcenter_3_object()(p1,p2,p3); 00223 00224 const FT denom = distance(c, fh.first->get_facet_surface_center(fh.second)); 00225 00226 if(denom == FT(0)) { 00227 q = 1; 00228 } 00229 else { 00230 q = B / denom; 00231 } 00232 return q < FT(1); 00233 } 00234 }; // end Curvature_size_criterion 00235 00236 // Uniform size Criterion class 00237 template <class Tr> 00238 class Uniform_size_criterion : public Refine_criterion <Tr> { 00239 public: 00240 typedef typename Refine_criterion <Tr>::Quality Quality; 00241 00242 private: 00243 typedef typename Refine_criterion <Tr>::Facet Facet; 00244 typedef typename Tr::Point Point; 00245 00246 Quality B; 00247 00248 public: 00249 // Nb: the default bound of the criterion is such that the criterion 00250 // is always fulfilled 00251 Uniform_size_criterion(const Quality b = 1000) : B(b * b) {} 00252 00253 inline 00254 Quality bound() const { return CGAL::sqrt (B); } 00255 00256 inline 00257 void set_bound(const Quality b) { B = b * b; }; 00258 00259 00260 bool is_bad (const Facet& fh, Quality& q) const { 00261 CGAL_assertion (fh.first->is_facet_on_surface (fh.second)); 00262 00263 if(B == Quality(0)) { 00264 q = 1; 00265 return false; 00266 } 00267 00268 typedef typename Tr::Geom_traits Geom_traits; 00269 typedef typename Geom_traits::FT FT; 00270 Geom_traits gt; 00271 00272 const Point& p1 = fh.first->vertex ((fh.second+1)&3)->point(); 00273 00274 q = B / gt.compute_squared_distance_3_object() 00275 (p1, fh.first->get_facet_surface_center (fh.second)); 00276 return q < FT(1); 00277 } 00278 }; // end Uniform_size_criterion 00279 00280 // Edge size Criterion class 00281 template <class Tr> 00282 class Edge_size_criterion : public Refine_criterion <Tr> { 00283 public: 00284 typedef typename Refine_criterion <Tr>::Quality Quality; 00285 00286 private: 00287 typedef typename Refine_criterion <Tr>::Facet Facet; 00288 typedef typename Tr::Point Point; 00289 00290 Quality B; 00291 00292 public: 00293 // Nb: the default bound of the criterion is such that the criterion 00294 // is always fulfilled 00295 Edge_size_criterion(const Quality b = 1000) : B(b * b) {} 00296 00297 inline 00298 Quality bound() const { return std::sqrt (B); } 00299 00300 inline 00301 void set_bound(const Quality b) { B = b * b; }; 00302 00303 00304 bool is_bad (const Facet& fh, Quality& q) const { 00305 typedef typename Tr::Geom_traits Geom_traits; 00306 typedef typename Geom_traits::FT FT; 00307 Geom_traits gt; 00308 00309 const Point& p1 = fh.first->vertex ((fh.second+1)&3)->point(); 00310 const Point& p2 = fh.first->vertex ((fh.second+2)&3)->point(); 00311 const Point& p3 = fh.first->vertex ((fh.second+3)&3)->point(); 00312 00313 const FT d12 = gt.compute_squared_distance_3_object() (p1, p2); 00314 const FT d13 = gt.compute_squared_distance_3_object() (p1, p3); 00315 const FT d23 = gt.compute_squared_distance_3_object() (p2, p3); 00316 00317 if (d12 > d13) { 00318 if (d12 > d23) 00319 q = B / d12; 00320 else 00321 q = B / d23; 00322 } 00323 else 00324 q = B / d13; 00325 return q < FT(1); 00326 } 00327 00328 }; // end Edge_size_criterion 00329 00330 00331 } // namespace Surface_mesher 00332 00333 } // namespace CGAL 00334 00335 00336 #endif // end CGAL_SURFACE_MESHER_STANDARD_CRITERIA_H 00337