cgma
CubitLoops.hpp
Go to the documentation of this file.
00001 #ifndef CUBIT_LOOPS_HPP
00002 #define CUBIT_LOOPS_HPP
00003 
00004 #include "CubitDefines.h"
00005 #include <vector>
00006 #include <set>
00007 #include <map>
00008 
00009 template <class C, class V>
00010 class CubitLoops
00011 {
00012 public:
00013   struct CoEdge
00014   {
00015     C* curve;
00016     V* start;
00017     V* end;
00018     CubitSense sense;
00019   };
00020 
00021   static bool make_loops(std::vector<CoEdge>& coedges,
00022       std::vector<std::vector<CoEdge*> >& loops);
00023 
00024 private:
00025 
00026   static bool recursive_make_loop(V* start_vertex, CoEdge* coedge,
00027     std::set<CoEdge* >& used_coedges,
00028     std::multimap<V*, CoEdge*>& start_coedge_map,
00029     std::vector<CoEdge*>& loop);
00030 };
00031 
00032 template <class C, class V> inline
00033 bool CubitLoops<C, V>::recursive_make_loop(V* start_vertex, CoEdge* coedge,
00034     std::set<CoEdge* >& used_coedges,
00035     std::multimap<V*, CoEdge*>& start_coedge_map,
00036     std::vector<CoEdge*>& loop)
00037 {
00038   V* curr_vertex;
00039   if (coedge->sense == CUBIT_FORWARD)
00040     curr_vertex = coedge->end;
00041   else
00042     curr_vertex = coedge->start;
00043   loop.push_back(coedge);
00044   used_coedges.insert(coedge);
00045 
00046   while (curr_vertex != start_vertex) 
00047   {
00048     typename std::multimap<V*, CoEdge*>::iterator iter;
00049     typename std::multimap<V*, CoEdge*>::iterator last;
00050 
00051     iter = start_coedge_map.lower_bound(curr_vertex);
00052     last = start_coedge_map.upper_bound(curr_vertex);
00053 
00054     std::vector<CoEdge*> possible_coedges;
00055     for (/*preinitialized*/; iter != last; iter++)
00056     {
00057       if (used_coedges.find(iter->second) == used_coedges.end())
00058         possible_coedges.push_back(iter->second);
00059     }
00060 
00061     if (possible_coedges.size() == 0)
00062       return false;
00063     else if (possible_coedges.size() == 1)
00064     {
00065       coedge = possible_coedges[0];
00066       loop.push_back(coedge);
00067       used_coedges.insert(coedge);
00068       if (coedge->sense == CUBIT_FORWARD)
00069         curr_vertex = coedge->end;
00070       else
00071         curr_vertex = coedge->start;
00072     }
00073     else
00074     {
00075       for (size_t i=0; i<possible_coedges.size(); i++)
00076       {
00077         std::vector<CoEdge*> sub_loop;
00078         if (recursive_make_loop(curr_vertex, possible_coedges[i], used_coedges, start_coedge_map, sub_loop) )
00079         {
00080           loop.insert(loop.end(), sub_loop.begin(), sub_loop.end());
00081         }
00082         else
00083         {
00084           for (size_t j=0; j<sub_loop.size(); j++)
00085             used_coedges.erase(sub_loop[j]);
00086           coedge = possible_coedges[i];
00087         }
00088       }
00089       loop.push_back(coedge);
00090       used_coedges.insert(coedge);
00091       if (coedge->sense == CUBIT_FORWARD)
00092         curr_vertex = coedge->end;
00093       else
00094         curr_vertex = coedge->start;
00095     }
00096   }
00097 
00098   return true;
00099 }
00100 
00101 template <class C, class V> inline
00102 bool CubitLoops<C, V>::make_loops(std::vector<CoEdge>& coedges,
00103       std::vector<std::vector<CoEdge*> >& loops)
00104 {
00105   std::multimap<V*, CoEdge*> start_coedge_map;
00106 
00107   for (size_t i=0; i<coedges.size(); i++)
00108   {
00109     if (coedges[i].sense == CUBIT_FORWARD)
00110       start_coedge_map.insert(std::make_pair(coedges[i].start, &coedges[i]));
00111     else
00112       start_coedge_map.insert(std::make_pair(coedges[i].end, &coedges[i]));
00113   }
00114 
00115   std::set<CoEdge*> used_coedges;
00116   for (size_t i=0; i<coedges.size(); i++)
00117   {
00118     if (used_coedges.find(&coedges[i]) != used_coedges.end())
00119       continue;
00120     V* start_vertex;
00121     if (coedges[i].sense == CUBIT_FORWARD)
00122       start_vertex = coedges[i].start;
00123     else
00124       start_vertex = coedges[i].end;
00125 
00126     typename std::multimap<V*, CoEdge*>::iterator iter;
00127     typename std::multimap<V*, CoEdge*>::iterator last;
00128     iter = start_coedge_map.lower_bound(start_vertex);
00129     last = start_coedge_map.upper_bound(start_vertex);
00130     std::vector<CoEdge*> loop;
00131 
00132     for (/*preinitialized*/; iter != last; iter++)
00133     {
00134       std::vector<CoEdge*> sub_loop;
00135       recursive_make_loop(start_vertex, iter->second, used_coedges, 
00136                           start_coedge_map, loop);
00137     }
00138 
00139     if (loop.empty())
00140       return false;
00141     loops.push_back(std::vector<CoEdge*>(loop.begin(), loop.end()) );
00142   }
00143 
00144   if (coedges.size() != used_coedges.size())
00145     return false;
00146 
00147   return true;
00148 }
00149 
00150 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines