BWAPI
|
00001 // Copyright (c) 2002-2004 INRIA Sophia-Antipolis (France). 00002 // All rights reserved. 00003 // 00004 // This file is part of CGAL (www.cgal.org); you can redistribute it and/or 00005 // modify it under the terms of the GNU Lesser General Public License as 00006 // published by the Free Software Foundation; version 2.1 of the License. 00007 // See the file LICENSE.LGPL distributed with CGAL. 00008 // 00009 // Licensees holding a valid commercial license may use this file in 00010 // accordance with the commercial license agreement provided with the software. 00011 // 00012 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 00013 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 00014 // 00015 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Qt_widget/include/CGAL/apply_to_range.h $ 00016 // $Id: apply_to_range.h 44130 2008-07-12 21:58:52Z spion $ 00017 // 00018 // 00019 // Author(s) : Radu Ursu 00020 00021 #ifndef CGAL_apply_to_range_h 00022 #define CGAL_apply_to_range_h 00023 00024 #include <CGAL/Triangulation_2.h> 00025 #include <CGAL/Unique_hash_map.h> 00026 #include <stack> 00027 00028 namespace CGAL{ 00029 00030 00031 template <class Tr, class Fct, class R> 00032 void apply_to_range(const Tr &t, 00033 const Point_2<R> &p1, const Point_2<R> &p2, 00034 Fct& fct) 00035 { 00036 if (t.dimension()<2) return; 00037 typedef typename Tr::Point POINT; 00038 typedef typename Tr::Segment SEGMENT; 00039 typedef typename Tr::Triangle TRIANGLE; 00040 typedef typename Tr::Face_handle hFACE; 00041 typedef typename Tr::Vertex_handle hVERTEX; 00042 typedef typename Tr::Line_face_circulator LFC; 00043 typedef typename Tr::Finite_vertices_iterator FVI; 00044 typedef typename Tr::Finite_faces_iterator FFI; 00045 typedef typename Kernel_traits<POINT>::Kernel K; 00046 typedef typename K::FT FT; 00047 00048 LFC l1, l2, l3, l4; //the faces that intersect the pixmap RECTANGLE 00049 hFACE hface1, hface2, 00050 hface3, hface4; //the faces where we start to search 00051 FT xr_left, yr_top, 00052 xr_right, yr_bottom;//the coordinates of the screen boundaries 00053 CGAL::Unique_hash_map<hFACE, bool> visited(false);//used for DFS 00054 std::stack<hFACE> face_stack; //used for DFS 00055 00056 xr_left = p1.x(); xr_right = p2.x(); 00057 yr_top = p1.y(); yr_bottom = p2.y(); 00058 00059 hface1 = t.locate(POINT(xr_left, yr_top)); 00060 hface2 = t.locate(POINT(xr_right, yr_top)); 00061 hface3 = t.locate(POINT(xr_right, yr_bottom)); 00062 hface4 = t.locate(POINT(xr_left, yr_bottom)); 00063 00064 l1 = t.line_walk(POINT(xr_left, yr_top), POINT(xr_right, yr_top), hface1); 00065 l2 = t.line_walk(POINT(xr_right, yr_top), POINT(xr_right, yr_bottom), hface2); 00066 l3 = t.line_walk(POINT(xr_right, yr_bottom), POINT(xr_left, yr_bottom), hface3); 00067 l4 = t.line_walk(POINT(xr_left, yr_bottom), POINT(xr_left, yr_top), hface4); 00068 00069 //test if everything is inside or outside 00070 if( (l1 == (Nullptr_t) NULL) && (l2 == (Nullptr_t) NULL) && 00071 (l3 == (Nullptr_t) NULL) && (l4 == (Nullptr_t) NULL)) 00072 { 00073 FVI v = t.finite_vertices_begin(); 00074 if((*v).point().x() < xr_left || (*v).point().x() > xr_right || 00075 (*v).point().y() < yr_bottom || (*v).point().y() > yr_top) //true if everything is outside 00076 return; 00077 else{ //everything is inside 00078 FFI it = t.finite_faces_begin(); 00079 while(it != t.finite_faces_end()) 00080 { 00081 fct(it); 00082 it++; 00083 } 00084 } 00085 return; 00086 } 00087 00088 //if we are here, then a part of the triangulation is inside, the other is outside 00089 00090 //put all the faces on the boundaries in the stack and the map 00091 if(l1 != (Nullptr_t) NULL) //found at least one face that intersect the TOP segment 00092 { 00093 while (t.is_infinite(l1)) l1++; //we should start with a finite face 00094 do{ //put all of them in the stack; 00095 face_stack.push(l1); 00096 visited[l1] = true; 00097 l1++; 00098 }while(!t.is_infinite(l1) && 00099 t.triangle(l1).has_on_unbounded_side(POINT(xr_right, yr_top))); 00100 } 00101 if(l2 != (Nullptr_t) NULL) //found at least one face that intersect the RIGHT segment 00102 { 00103 while (t.is_infinite(l2)) l2++; //we should start with a finite face 00104 do{ //put all of them in the stack; 00105 if(!visited[l2]){ 00106 face_stack.push(l2); 00107 visited[l2] = true; 00108 } 00109 l2++; 00110 }while(!t.is_infinite(l2) && 00111 t.triangle(l2).has_on_unbounded_side(POINT(xr_right, yr_bottom))); 00112 } 00113 if(l3 != (Nullptr_t) NULL) //found at least one face that intersect the BOTTOM segment 00114 { 00115 while (t.is_infinite(l3)) l3++; //we should start with a finite face 00116 do{ //put all of them in the stack; 00117 if(!visited[l3]){ 00118 face_stack.push(l3); 00119 visited[l3] = true; 00120 } 00121 l3++; 00122 }while(!t.is_infinite(l3) && 00123 t.triangle(l3).has_on_unbounded_side(POINT(xr_left, yr_bottom))); 00124 } 00125 if(l4 != (Nullptr_t) NULL) //found at least one face that intersect the LEFT segment 00126 { 00127 while (t.is_infinite(l4)) l4++; //we should start with a finite face 00128 do{ //put all of them in the stack; 00129 if(!visited[l4]){ 00130 face_stack.push(l4); 00131 visited[l4] = true; 00132 } 00133 l4++; 00134 }while(!t.is_infinite(l4) && 00135 t.triangle(l4).has_on_unbounded_side(POINT(xr_left, yr_top))); 00136 } 00137 00138 //HERE we begin to walk through the faces DFS 00139 hFACE hf; 00140 typename CGAL::Unique_hash_map<hFACE,bool>::Data& 00141 data_ref_start(visited[hf]); 00142 data_ref_start = true; 00143 while(!face_stack.empty()){ 00144 hf = face_stack.top(); 00145 face_stack.pop(); //done with this face 00146 for (int i=0; i<3; i++){ //visit all the neighbors 00147 if(!visited[(*hf).neighbor(i)] ) 00148 if(!t.is_infinite((*hf).neighbor(i))){ //true if it is not an infinite face 00149 hVERTEX hv = (*(*hf).neighbor(i)).vertex((*(*hf).neighbor(i)).index(hf)); 00150 if(!((*hv).point().x() < xr_left || (*hv).point().x() > xr_right || 00151 (*hv).point().y() < yr_bottom || (*hv).point().y() > yr_top)) //true if the vertex is outside 00152 face_stack.push((*hf).neighbor(i)); 00153 typename CGAL::Unique_hash_map<hFACE,bool>::Data& 00154 data_ref(visited[(*hf).neighbor(i)]); 00155 data_ref = true; 00156 } 00157 } 00158 fct(hf); 00159 } 00160 } 00161 00162 }//end namespace 00163 00164 #endif