BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/apply_to_range.h
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines