Go to the documentation of this file.00001 #ifndef OPENTISSUE_CORE_CONTAINERS_T4MESH_T4EDGES_H
00002 #define OPENTISSUE_CORE_CONTAINERS_T4MESH_T4EDGES_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <list>
00013 #include <cassert>
00014
00015 namespace OpenTissue
00016 {
00017 namespace t4mesh
00018 {
00019
00025 template<typename M, typename E>
00026 class T4Edge : public E
00027 {
00028 public:
00029
00030 typedef M mesh_type;
00031 typedef E edge_traits;
00032 typedef T4Edge<M,E> edge_type;
00033 typedef typename mesh_type::index_type index_type;
00034
00035 protected:
00036
00037 index_type m_idxA;
00038 index_type m_idxB;
00039
00040 public:
00041
00042 T4Edge()
00043 : m_idxA(-1)
00044 , m_idxB(-1)
00045 {}
00046
00047 T4Edge(index_type const & indexA, index_type const & indexB)
00048 : m_idxA(indexA)
00049 , m_idxB(indexB)
00050 {}
00051
00052 public:
00053
00054 index_type const & idxA() const { return m_idxA; }
00055 index_type const & idxB() const { return m_idxB; }
00056
00057 bool operator==(edge_type const & edge) const
00058 {
00059 if(m_idxA==edge.idxA() && m_idxB==edge.idxB())
00060 return true;
00061 if(m_idxB==edge.idxA() && m_idxA==edge.idxB())
00062 return true;
00063 return false;
00064 }
00065
00066 bool operator!=(edge_type const & edge)const{ return !((*this)==edge); }
00067
00068 };
00069
00081 template<class M, typename E >
00082 class T4Edges
00083 {
00084 public:
00085
00086 typedef M mesh_type;
00087 typedef E edge_traits;
00088 typedef T4Edge<M,E> edge_type;
00089 typedef typename mesh_type::index_type index_type;
00090 typedef std::list<edge_type> edge_container;
00091 typedef typename edge_container::iterator edge_iterator;
00092 typedef typename edge_container::const_iterator const_edge_iterator;
00093
00094 protected:
00095
00096 typedef enum{white,grey,black} color_type;
00097 typedef std::vector<color_type> color_container;
00098 typedef typename mesh_type::node_type node_type;
00099 typedef typename node_type::tetrahedron_circulator tetrahedron_type;
00100 typedef std::list<node_type*> work_queue;
00101
00102 protected:
00103
00104 edge_container m_edges;
00105
00106 public:
00107
00108 edge_iterator begin() { return m_edges.begin(); }
00109 edge_iterator end() { return m_edges.end(); }
00110 const_edge_iterator begin() const { return m_edges.begin(); }
00111 const_edge_iterator end() const { return m_edges.end(); }
00112
00113
00114 protected:
00115
00120 struct VisitT4Edge
00121 {
00122 void visit(
00123 index_type & idxA
00124 , index_type & idxB
00125 , work_queue & work
00126 , color_container & colors
00127 , edge_container & edges
00128 , mesh_type & mesh
00129 )
00130 {
00131 if(idxA==idxB)
00132 return;
00133
00134
00135
00136 if(colors[idxB]==white)
00137 {
00138 colors[idxB] = grey;
00139 work.push_back(&(*(mesh.node(idxB))));
00140 }
00141 if(colors[idxB]!=black)
00142 {
00143 edges.push_back(edge_type(idxA,idxB));
00144 }
00145 }
00146 };
00147
00148 public:
00149
00150 T4Edges(){}
00151
00156 T4Edges(mesh_type & mesh)
00157 {
00158 index_type idxA,idxB;
00159
00160 color_container colors(mesh.size_nodes());
00161 std::fill(colors.begin(),colors.end(),white);
00162 node_type * node = &(*(mesh.node(0)));
00163 colors[0]=grey;
00164 work_queue work;
00165 work.push_back(node);
00166 while(!work.empty())
00167 {
00168 node = work.back();
00169 work.pop_back();
00170 idxA = node->idx();
00171
00172 assert(colors[idxA] == grey || !"T4Edges(mesh): Encounted non-greay node");
00173
00174
00175
00176 std::list<index_type> neighbors;
00177 for(tetrahedron_type T = node->begin();T!=node->end();++T)
00178 {
00179 idxB = T->i()->idx();
00180 if(idxB != idxA)
00181 neighbors.push_back(idxB);
00182 idxB = T->j()->idx();
00183 if(idxB != idxA)
00184 neighbors.push_back(idxB);
00185 idxB = T->k()->idx();
00186 if(idxB != idxA)
00187 neighbors.push_back(idxB);
00188 idxB = T->m()->idx();
00189 if(idxB != idxA)
00190 neighbors.push_back(idxB);
00191 }
00192 neighbors.sort();
00193 neighbors.unique();
00194
00195 for(typename std::list<index_type>::iterator n = neighbors.begin();n!=neighbors.end();++n)
00196 VisitT4Edge().visit(idxA, *n ,work,colors,m_edges,mesh);
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209 colors[idxA] = black;
00210 }
00211 };
00212
00213 };
00214
00215 }
00216 }
00217
00218
00219 #endif