annotate DEPENDENCIES/generic/include/boost/graph/detail/self_avoiding_walk.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 //=======================================================================
Chris@16 2 // Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
Chris@16 3 // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
Chris@16 4 //
Chris@16 5 // Distributed under the Boost Software License, Version 1.0. (See
Chris@16 6 // accompanying file LICENSE_1_0.txt or copy at
Chris@16 7 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 8 //=======================================================================
Chris@16 9 #ifndef BOOST_SELF_AVOIDING_WALK_HPP
Chris@16 10 #define BOOST_SELF_AVOIDING_WALK_HPP
Chris@16 11
Chris@16 12 /*
Chris@16 13 This file defines necessary components for SAW.
Chris@16 14
Chris@16 15 mesh language: (defined by myself to clearify what is what)
Chris@16 16 A triangle in mesh is called an triangle.
Chris@16 17 An edge in mesh is called an line.
Chris@16 18 A vertex in mesh is called a point.
Chris@16 19
Chris@16 20 A triangular mesh corresponds to a graph in which a vertex is a
Chris@16 21 triangle and an edge(u, v) stands for triangle u and triangle v
Chris@16 22 share an line.
Chris@16 23
Chris@16 24 After this point, a vertex always refers to vertex in graph,
Chris@16 25 therefore it is a traingle in mesh.
Chris@16 26
Chris@16 27 */
Chris@16 28
Chris@16 29 #include <utility>
Chris@16 30 #include <boost/config.hpp>
Chris@16 31 #include <boost/graph/graph_traits.hpp>
Chris@16 32 #include <boost/property_map/property_map.hpp>
Chris@16 33
Chris@16 34 #define SAW_SENTINAL -1
Chris@16 35
Chris@16 36 namespace boost {
Chris@16 37
Chris@16 38 template <class T1, class T2, class T3>
Chris@16 39 struct triple {
Chris@16 40 T1 first;
Chris@16 41 T2 second;
Chris@16 42 T3 third;
Chris@16 43 triple(const T1& a, const T2& b, const T3& c) : first(a), second(b), third(c) {}
Chris@16 44 triple() : first(SAW_SENTINAL), second(SAW_SENTINAL), third(SAW_SENTINAL) {}
Chris@16 45 };
Chris@16 46
Chris@16 47 typedef triple<int, int, int> Triple;
Chris@16 48
Chris@16 49 /* Define a vertex property which has a triangle inside. Triangle is
Chris@16 50 represented by a triple. */
Chris@16 51 struct triangle_tag { enum { num = 100 }; };
Chris@16 52 typedef property<triangle_tag,Triple> triangle_property;
Chris@16 53
Chris@16 54 /* Define an edge property with a line. A line is represented by a
Chris@16 55 pair. This is not required for SAW though.
Chris@16 56 */
Chris@16 57 struct line_tag { enum { num = 101 }; };
Chris@16 58 template <class T> struct line_property
Chris@16 59 : public property<line_tag, std::pair<T,T> > { };
Chris@16 60
Chris@16 61 /*Precondition: Points in a Triangle are in order */
Chris@16 62 template <class Triangle, class Line>
Chris@16 63 inline void get_sharing(const Triangle& a, const Triangle& b, Line& l)
Chris@16 64 {
Chris@16 65 l.first = SAW_SENTINAL;
Chris@16 66 l.second = SAW_SENTINAL;
Chris@16 67
Chris@16 68 if ( a.first == b.first ) {
Chris@16 69 l.first = a.first;
Chris@16 70 if ( a.second == b.second || a.second == b.third )
Chris@16 71 l.second = a.second;
Chris@16 72 else if ( a.third == b.second || a.third == b.third )
Chris@16 73 l.second = a.third;
Chris@16 74
Chris@16 75 } else if ( a.first == b.second ) {
Chris@16 76 l.first = a.first;
Chris@16 77 if ( a.second == b.third )
Chris@16 78 l.second = a.second;
Chris@16 79 else if ( a.third == b.third )
Chris@16 80 l.second = a.third;
Chris@16 81
Chris@16 82 } else if ( a.first == b.third ) {
Chris@16 83 l.first = a.first;
Chris@16 84
Chris@16 85
Chris@16 86 } else if ( a.second == b.first ) {
Chris@16 87 l.first = a.second;
Chris@16 88 if ( a.third == b.second || a.third == b.third )
Chris@16 89 l.second = a.third;
Chris@16 90
Chris@16 91 } else if ( a.second == b.second ) {
Chris@16 92 l.first = a.second;
Chris@16 93 if ( a.third == b.third )
Chris@16 94 l.second = a.third;
Chris@16 95
Chris@16 96 } else if ( a.second == b.third ) {
Chris@16 97 l.first = a.second;
Chris@16 98
Chris@16 99
Chris@16 100 } else if ( a.third == b.first
Chris@16 101 || a.third == b.second
Chris@16 102 || a.third == b.third )
Chris@16 103 l.first = a.third;
Chris@16 104
Chris@16 105 /*Make it in order*/
Chris@16 106 if ( l.first > l.second ) {
Chris@16 107 typename Line::first_type i = l.first;
Chris@16 108 l.first = l.second;
Chris@16 109 l.second = i;
Chris@16 110 }
Chris@16 111
Chris@16 112 }
Chris@16 113
Chris@16 114 template <class TriangleDecorator, class Vertex, class Line>
Chris@16 115 struct get_vertex_sharing {
Chris@16 116 typedef std::pair<Vertex, Line> Pair;
Chris@16 117 get_vertex_sharing(const TriangleDecorator& _td) : td(_td) {}
Chris@16 118 inline Line operator()(const Vertex& u, const Vertex& v) const {
Chris@16 119 Line l;
Chris@16 120 get_sharing(td[u], td[v], l);
Chris@16 121 return l;
Chris@16 122 }
Chris@16 123 inline Line operator()(const Pair& u, const Vertex& v) const {
Chris@16 124 Line l;
Chris@16 125 get_sharing(td[u.first], td[v], l);
Chris@16 126 return l;
Chris@16 127 }
Chris@16 128 inline Line operator()(const Pair& u, const Pair& v) const {
Chris@16 129 Line l;
Chris@16 130 get_sharing(td[u.first], td[v.first], l);
Chris@16 131 return l;
Chris@16 132 }
Chris@16 133 TriangleDecorator td;
Chris@16 134 };
Chris@16 135
Chris@16 136 /* HList has to be a handle of data holder so that pass-by-value is
Chris@16 137 * in right logic.
Chris@16 138 *
Chris@16 139 * The element of HList is a pair of vertex and line. (remember a
Chris@16 140 * line is a pair of two ints.). That indicates the walk w from
Chris@16 141 * current vertex is across line. (If the first of line is -1, it is
Chris@16 142 * a point though.
Chris@16 143 */
Chris@16 144 template < class TriangleDecorator, class HList, class IteratorD>
Chris@16 145 class SAW_visitor
Chris@16 146 : public bfs_visitor<>, public dfs_visitor<>
Chris@16 147 {
Chris@16 148 typedef typename boost::property_traits<IteratorD>::value_type iter;
Chris@16 149 /*use boost shared_ptr*/
Chris@16 150 typedef typename HList::element_type::value_type::second_type Line;
Chris@16 151 public:
Chris@16 152
Chris@16 153 typedef tree_edge_tag category;
Chris@16 154
Chris@16 155 inline SAW_visitor(TriangleDecorator _td, HList _hlist, IteratorD ia)
Chris@16 156 : td(_td), hlist(_hlist), iter_d(ia) {}
Chris@16 157
Chris@16 158 template <class Vertex, class Graph>
Chris@16 159 inline void start_vertex(Vertex v, Graph&) {
Chris@16 160 Line l1;
Chris@16 161 l1.first = SAW_SENTINAL;
Chris@16 162 l1.second = SAW_SENTINAL;
Chris@16 163 hlist->push_front(std::make_pair(v, l1));
Chris@16 164 iter_d[v] = hlist->begin();
Chris@16 165 }
Chris@16 166
Chris@16 167 /*Several symbols:
Chris@16 168 w(i): i-th triangle in walk w
Chris@16 169 w(i) |- w(i+1): w enter w(i+1) from w(i) over a line
Chris@16 170 w(i) ~> w(i+1): w enter w(i+1) from w(i) over a point
Chris@16 171 w(i) -> w(i+1): w enter w(i+1) from w(i)
Chris@16 172 w(i) ^ w(i+1): the line or point w go over from w(i) to w(i+1)
Chris@16 173 */
Chris@16 174 template <class Edge, class Graph>
Chris@16 175 bool tree_edge(Edge e, Graph& G) {
Chris@16 176 using std::make_pair;
Chris@16 177 typedef typename boost::graph_traits<Graph>::vertex_descriptor Vertex;
Chris@16 178 Vertex tau = target(e, G);
Chris@16 179 Vertex i = source(e, G);
Chris@16 180
Chris@16 181 get_vertex_sharing<TriangleDecorator, Vertex, Line> get_sharing_line(td);
Chris@16 182
Chris@16 183 Line tau_i = get_sharing_line(tau, i);
Chris@16 184
Chris@16 185 iter w_end = hlist->end();
Chris@16 186
Chris@16 187 iter w_i = iter_d[i];
Chris@16 188
Chris@16 189 iter w_i_m_1 = w_i;
Chris@16 190 iter w_i_p_1 = w_i;
Chris@16 191
Chris@16 192 /*----------------------------------------------------------
Chris@16 193 * true false
Chris@16 194 *==========================================================
Chris@16 195 *a w(i-1) |- w(i) w(i-1) ~> w(i) or w(i-1) is null
Chris@16 196 *----------------------------------------------------------
Chris@16 197 *b w(i) |- w(i+1) w(i) ~> w(i+1) or no w(i+1) yet
Chris@16 198 *----------------------------------------------------------
Chris@16 199 */
Chris@16 200
Chris@16 201 bool a = false, b = false;
Chris@16 202
Chris@16 203 --w_i_m_1;
Chris@16 204 ++w_i_p_1;
Chris@16 205 b = ( w_i->second.first != SAW_SENTINAL );
Chris@16 206
Chris@16 207 if ( w_i_m_1 != w_end ) {
Chris@16 208 a = ( w_i_m_1->second.first != SAW_SENTINAL );
Chris@16 209 }
Chris@16 210
Chris@16 211 if ( a ) {
Chris@16 212
Chris@16 213 if ( b ) {
Chris@16 214 /*Case 1:
Chris@16 215
Chris@16 216 w(i-1) |- w(i) |- w(i+1)
Chris@16 217 */
Chris@16 218 Line l1 = get_sharing_line(*w_i_m_1, tau);
Chris@16 219
Chris@16 220 iter w_i_m_2 = w_i_m_1;
Chris@16 221 --w_i_m_2;
Chris@16 222
Chris@16 223 bool c = true;
Chris@16 224
Chris@16 225 if ( w_i_m_2 != w_end ) {
Chris@16 226 c = w_i_m_2->second != l1;
Chris@16 227 }
Chris@16 228
Chris@16 229 if ( c ) { /* w(i-1) ^ tau != w(i-2) ^ w(i-1) */
Chris@16 230 /*extension: w(i-1) -> tau |- w(i) */
Chris@16 231 w_i_m_1->second = l1;
Chris@16 232 /*insert(pos, const T&) is to insert before pos*/
Chris@16 233 iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i));
Chris@16 234
Chris@16 235 } else { /* w(i-1) ^ tau == w(i-2) ^ w(i-1) */
Chris@16 236 /*must be w(i-2) ~> w(i-1) */
Chris@16 237
Chris@16 238 bool d = true;
Chris@16 239 //need to handle the case when w_i_p_1 is null
Chris@16 240 Line l3 = get_sharing_line(*w_i_p_1, tau);
Chris@16 241 if ( w_i_p_1 != w_end )
Chris@16 242 d = w_i_p_1->second != l3;
Chris@16 243 if ( d ) { /* w(i+1) ^ tau != w(i+1) ^ w(i+2) */
Chris@16 244 /*extension: w(i) |- tau -> w(i+1) */
Chris@16 245 w_i->second = tau_i;
Chris@16 246 iter_d[tau] = hlist->insert(w_i_p_1, make_pair(tau, l3));
Chris@16 247 } else { /* w(i+1) ^ tau == w(i+1) ^ w(i+2) */
Chris@16 248 /*must be w(1+1) ~> w(i+2) */
Chris@16 249 Line l5 = get_sharing_line(*w_i_m_1, *w_i_p_1);
Chris@16 250 if ( l5 != w_i_p_1->second ) { /* w(i-1) ^ w(i+1) != w(i+1) ^ w(i+2) */
Chris@16 251 /*extension: w(i-2) -> tau |- w(i) |- w(i-1) -> w(i+1) */
Chris@16 252 w_i_m_2->second = get_sharing_line(*w_i_m_2, tau);
Chris@16 253 iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i));
Chris@16 254 w_i->second = w_i_m_1->second;
Chris@16 255 w_i_m_1->second = l5;
Chris@16 256 iter_d[w_i_m_1->first] = hlist->insert(w_i_p_1, *w_i_m_1);
Chris@16 257 hlist->erase(w_i_m_1);
Chris@16 258 } else {
Chris@16 259 /*mesh is tetrahedral*/
Chris@16 260 // dont know what that means.
Chris@16 261 ;
Chris@16 262 }
Chris@16 263 }
Chris@16 264
Chris@16 265 }
Chris@16 266 } else {
Chris@16 267 /*Case 2:
Chris@16 268
Chris@16 269 w(i-1) |- w(i) ~> w(1+1)
Chris@16 270 */
Chris@16 271
Chris@16 272 if ( w_i->second.second == tau_i.first
Chris@16 273 || w_i->second.second == tau_i.second ) { /*w(i) ^ w(i+1) < w(i) ^ tau*/
Chris@16 274 /*extension: w(i) |- tau -> w(i+1) */
Chris@16 275 w_i->second = tau_i;
Chris@16 276 Line l1 = get_sharing_line(*w_i_p_1, tau);
Chris@16 277 iter_d[tau] = hlist->insert(w_i_p_1, make_pair(tau, l1));
Chris@16 278 } else { /*w(i) ^ w(i+1) !< w(i) ^ tau*/
Chris@16 279 Line l1 = get_sharing_line(*w_i_m_1, tau);
Chris@16 280 bool c = true;
Chris@16 281 iter w_i_m_2 = w_i_m_1;
Chris@16 282 --w_i_m_2;
Chris@16 283 if ( w_i_m_2 != w_end )
Chris@16 284 c = l1 != w_i_m_2->second;
Chris@16 285 if (c) { /*w(i-1) ^ tau != w(i-2) ^ w(i-1)*/
Chris@16 286 /*extension: w(i-1) -> tau |- w(i)*/
Chris@16 287 w_i_m_1->second = l1;
Chris@16 288 iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i));
Chris@16 289 } else { /*w(i-1) ^ tau == w(i-2) ^ w(i-1)*/
Chris@16 290 /*must be w(i-2)~>w(i-1)*/
Chris@16 291 /*extension: w(i-2) -> tau |- w(i) |- w(i-1) -> w(i+1)*/
Chris@16 292 w_i_m_2->second = get_sharing_line(*w_i_m_2, tau);
Chris@16 293 iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i));
Chris@16 294 w_i->second = w_i_m_1->second;
Chris@16 295 w_i_m_1->second = get_sharing_line(*w_i_m_1, *w_i_p_1);
Chris@16 296 iter_d[w_i_m_1->first] = hlist->insert(w_i_p_1, *w_i_m_1);
Chris@16 297 hlist->erase(w_i_m_1);
Chris@16 298 }
Chris@16 299
Chris@16 300 }
Chris@16 301
Chris@16 302 }
Chris@16 303
Chris@16 304 } else {
Chris@16 305
Chris@16 306 if ( b ) {
Chris@16 307 /*Case 3:
Chris@16 308
Chris@16 309 w(i-1) ~> w(i) |- w(i+1)
Chris@16 310 */
Chris@16 311 bool c = false;
Chris@16 312 if ( w_i_m_1 != w_end )
Chris@16 313 c = ( w_i_m_1->second.second == tau_i.first)
Chris@16 314 || ( w_i_m_1->second.second == tau_i.second);
Chris@16 315
Chris@16 316 if ( c ) { /*w(i-1) ^ w(i) < w(i) ^ tau*/
Chris@16 317 /* extension: w(i-1) -> tau |- w(i) */
Chris@16 318 if ( w_i_m_1 != w_end )
Chris@16 319 w_i_m_1->second = get_sharing_line(*w_i_m_1, tau);
Chris@16 320 iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i));
Chris@16 321 } else {
Chris@16 322 bool d = true;
Chris@16 323 Line l1;
Chris@16 324 l1.first = SAW_SENTINAL;
Chris@16 325 l1.second = SAW_SENTINAL;
Chris@16 326 if ( w_i_p_1 != w_end ) {
Chris@16 327 l1 = get_sharing_line(*w_i_p_1, tau);
Chris@16 328 d = l1 != w_i_p_1->second;
Chris@16 329 }
Chris@16 330 if (d) { /*w(i+1) ^ tau != w(i+1) ^ w(i+2)*/
Chris@16 331 /*extension: w(i) |- tau -> w(i+1) */
Chris@16 332 w_i->second = tau_i;
Chris@16 333 iter_d[tau] = hlist->insert(w_i_p_1, make_pair(tau, l1));
Chris@16 334 } else {
Chris@16 335 /*must be w(i+1) ~> w(i+2)*/
Chris@16 336 /*extension: w(i-1) -> w(i+1) |- w(i) |- tau -> w(i+2) */
Chris@16 337 iter w_i_p_2 = w_i_p_1;
Chris@16 338 ++w_i_p_2;
Chris@16 339
Chris@16 340 w_i_p_1->second = w_i->second;
Chris@16 341 iter_d[i] = hlist->insert(w_i_p_2, make_pair(i, tau_i));
Chris@16 342 hlist->erase(w_i);
Chris@16 343 Line l2 = get_sharing_line(*w_i_p_2, tau);
Chris@16 344 iter_d[tau] = hlist->insert(w_i_p_2, make_pair(tau, l2));
Chris@16 345 }
Chris@16 346 }
Chris@16 347
Chris@16 348 } else {
Chris@16 349 /*Case 4:
Chris@16 350
Chris@16 351 w(i-1) ~> w(i) ~> w(i+1)
Chris@16 352
Chris@16 353 */
Chris@16 354 bool c = false;
Chris@16 355 if ( w_i_m_1 != w_end ) {
Chris@16 356 c = (w_i_m_1->second.second == tau_i.first)
Chris@16 357 || (w_i_m_1->second.second == tau_i.second);
Chris@16 358 }
Chris@16 359 if ( c ) { /*w(i-1) ^ w(i) < w(i) ^ tau */
Chris@16 360 /*extension: w(i-1) -> tau |- w(i) */
Chris@16 361 if ( w_i_m_1 != w_end )
Chris@16 362 w_i_m_1->second = get_sharing_line(*w_i_m_1, tau);
Chris@16 363 iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i));
Chris@16 364 } else {
Chris@16 365 /*extension: w(i) |- tau -> w(i+1) */
Chris@16 366 w_i->second = tau_i;
Chris@16 367 Line l1;
Chris@16 368 l1.first = SAW_SENTINAL;
Chris@16 369 l1.second = SAW_SENTINAL;
Chris@16 370 if ( w_i_p_1 != w_end )
Chris@16 371 l1 = get_sharing_line(*w_i_p_1, tau);
Chris@16 372 iter_d[tau] = hlist->insert(w_i_p_1, make_pair(tau, l1));
Chris@16 373 }
Chris@16 374 }
Chris@16 375
Chris@16 376 }
Chris@16 377
Chris@16 378 return true;
Chris@16 379 }
Chris@16 380
Chris@16 381 protected:
Chris@16 382 TriangleDecorator td; /*a decorator for vertex*/
Chris@16 383 HList hlist;
Chris@16 384 /*This must be a handle of list to record the SAW
Chris@16 385 The element type of the list is pair<Vertex, Line>
Chris@16 386 */
Chris@16 387
Chris@16 388 IteratorD iter_d;
Chris@16 389 /*Problem statement: Need a fast access to w for triangle i.
Chris@16 390 *Possible solution: mantain an array to record.
Chris@16 391 iter_d[i] will return an iterator
Chris@16 392 which points to w(i), where i is a vertex
Chris@16 393 representing triangle i.
Chris@16 394 */
Chris@16 395 };
Chris@16 396
Chris@16 397 template <class Triangle, class HList, class Iterator>
Chris@16 398 inline
Chris@16 399 SAW_visitor<Triangle, HList, Iterator>
Chris@16 400 visit_SAW(Triangle t, HList hl, Iterator i) {
Chris@16 401 return SAW_visitor<Triangle, HList, Iterator>(t, hl, i);
Chris@16 402 }
Chris@16 403
Chris@16 404 template <class Tri, class HList, class Iter>
Chris@16 405 inline
Chris@16 406 SAW_visitor< random_access_iterator_property_map<Tri*,Tri,Tri&>,
Chris@16 407 HList, random_access_iterator_property_map<Iter*,Iter,Iter&> >
Chris@16 408 visit_SAW_ptr(Tri* t, HList hl, Iter* i) {
Chris@16 409 typedef random_access_iterator_property_map<Tri*,Tri,Tri&> TriD;
Chris@16 410 typedef random_access_iterator_property_map<Iter*,Iter,Iter&> IterD;
Chris@16 411 return SAW_visitor<TriD, HList, IterD>(t, hl, i);
Chris@16 412 }
Chris@16 413
Chris@16 414 // should also have combo's of pointers, and also const :(
Chris@16 415
Chris@16 416 }
Chris@16 417
Chris@16 418 #endif /*BOOST_SAW_H*/