00001
00002 #include "vtol_cycle_processor.h"
00003
00004
00005
00006 #include <vcl_vector.h>
00007 #include <vcl_algorithm.h>
00008 #include <vcl_iostream.h>
00009 #include <vcl_cmath.h>
00010
00011 #include <vsol/vsol_box_2d.h>
00012 #include <vsol/vsol_box_2d_sptr.h>
00013 #include <vdgl/vdgl_digital_curve.h>
00014 #include <vdgl/vdgl_interpolator.h>
00015 #include <vdgl/vdgl_edgel_chain.h>
00016
00017 #include <vtol/vtol_vertex.h>
00018 #include <vtol/vtol_vertex_2d.h>
00019 #include <vtol/vtol_one_chain.h>
00020 #include <vtol/vtol_edge.h>
00021 #include <vtol/vtol_edge_2d.h>
00022 #include <vtol/vtol_edge_2d_sptr.h>
00023
00024
00025 vtol_cycle_processor::vtol_cycle_processor(vcl_vector<vtol_edge_2d_sptr>& edges,
00026 bool debug1, bool debug2)
00027 {
00028 debug1_ = debug1;
00029 debug2_ = debug2;
00030 tolerance_ = 0;
00031 init(edges);
00032 }
00033
00034
00035
00036 static void edge_2d_erase(vcl_vector<vtol_edge_2d_sptr>& edges,
00037 vtol_edge_2d_sptr& e)
00038 {
00039 vcl_vector<vtol_edge_2d_sptr>::iterator eit =
00040 vcl_find(edges.begin(), edges.end(), e);
00041 if (eit == edges.end())
00042 return;
00043 edges.erase(eit);
00044 return;
00045 }
00046
00047
00048
00049 static void print_vertices(vcl_vector<vtol_vertex_sptr>& verts)
00050 {
00051 for (vcl_vector<vtol_vertex_sptr>::iterator vit = verts.begin();
00052 vit != verts.end(); ++vit)
00053 vcl_cout << *vit << '('
00054 << (*vit)->cast_to_vertex_2d()->x()<< ' '
00055 << (*vit)->cast_to_vertex_2d()->y()<< ")\n\n";
00056 }
00057
00058
00059
00060 static void print_edges(vcl_vector<vtol_edge_2d_sptr>& edges)
00061 {
00062 for (vcl_vector<vtol_edge_2d_sptr>::iterator eit = edges.begin();
00063 eit != edges.end(); ++eit)
00064 vcl_cout << *eit << '('
00065 << (*eit)->v1()->cast_to_vertex_2d()->x()<< ' '
00066 << (*eit)->v1()->cast_to_vertex_2d()->y()<< " |"
00067 << (*eit)->v2()->cast_to_vertex_2d()->x()<< ' '
00068 << (*eit)->v2()->cast_to_vertex_2d()->y()<< ")\n\n";
00069 }
00070
00071
00072
00073 static void print_edges(vcl_vector<vtol_edge_sptr>& edges)
00074 {
00075 for (vcl_vector<vtol_edge_sptr>::iterator eit = edges.begin();
00076 eit != edges.end(); ++eit)
00077 vcl_cout << *eit << '('
00078 << (*eit)->v1()->cast_to_vertex_2d()->x()<< ' '
00079 << (*eit)->v1()->cast_to_vertex_2d()->y()<< " |"
00080 << (*eit)->v2()->cast_to_vertex_2d()->x()<< ' '
00081 << (*eit)->v2()->cast_to_vertex_2d()->y()<< ")\n\n";
00082 }
00083
00084
00085
00086 static void pop_stacks(vertex_list& verts,
00087 vcl_vector<vtol_edge_2d_sptr>& edges,
00088 vtol_vertex_sptr& v,
00089 vcl_vector<vtol_edge_2d_sptr>& cycle_edges)
00090 {
00091 bool found = false;
00092 while (verts.size()&&edges.size()&&!found)
00093 {
00094 found = verts.back()==v;
00095 cycle_edges.push_back(edges.back());
00096 verts.pop_back();
00097 edges.pop_back();
00098 }
00099 if (!edges.size()&&verts.size())
00100 verts.clear();
00101 }
00102
00103
00104
00105
00106
00107 static bool used(vtol_edge_2d_sptr& e)
00108 {
00109 return e->get_user_flag(VSOL_FLAG1)&&e->get_user_flag(VSOL_FLAG2);
00110 }
00111
00112 static bool unused(vtol_edge_2d_sptr& e)
00113 {
00114 return !e->get_user_flag(VSOL_FLAG1)&&!e->get_user_flag(VSOL_FLAG2);
00115 }
00116
00117 static bool plus_used(vtol_edge_2d_sptr& e)
00118 {
00119 return e->get_user_flag(VSOL_FLAG1) != 0;
00120 }
00121
00122 static bool minus_used(vtol_edge_2d_sptr& e)
00123 {
00124 return e->get_user_flag(VSOL_FLAG2) != 0;
00125 }
00126
00127 static bool half_used(vtol_edge_2d_sptr& e)
00128 {
00129 return e->get_user_flag(VSOL_FLAG1) ^ e->get_user_flag(VSOL_FLAG2);
00130
00131 }
00132
00133
00134 static void use_plus(vtol_edge_2d_sptr& e)
00135 {
00136 e->set_user_flag(VSOL_FLAG1);
00137 }
00138
00139 static void use_minus(vtol_edge_2d_sptr& e)
00140 {
00141 e->set_user_flag(VSOL_FLAG2);
00142 }
00143
00144
00145
00146 static bool ccw(vtol_one_chain_sptr& ch)
00147 {
00148 return ch && ch->get_user_flag(VSOL_FLAG1) != 0;
00149 }
00150
00151 static bool cw(vtol_one_chain_sptr& ch)
00152 {
00153 return ch && ch->get_user_flag(VSOL_FLAG2) != 0;
00154 }
00155
00156
00157 static void set_ccw(vtol_one_chain_sptr& ch)
00158 {
00159 ch->set_user_flag(VSOL_FLAG1);
00160 }
00161
00162 static void set_cw(vtol_one_chain_sptr& ch)
00163 {
00164 ch->set_user_flag(VSOL_FLAG2);
00165 }
00166
00167
00168
00169 static void clear(vtol_edge_2d_sptr& e)
00170 {
00171 e->unset_user_flag(VSOL_FLAG1);
00172 e->unset_user_flag(VSOL_FLAG2);
00173 e->unset_user_flag(VSOL_FLAG3);
00174 }
00175
00176 #if 0 // only untouch(vtol_one_chain_sptr&) is used
00177 static void untouch(vtol_edge_2d_sptr& e)
00178 {
00179 e->unset_user_flag(VSOL_FLAG3);
00180 }
00181 #endif
00182
00183 static void touch(vtol_edge_2d_sptr& e)
00184 {
00185 e->set_user_flag(VSOL_FLAG3);
00186 }
00187
00188 static bool touched(vtol_edge_2d_sptr& e)
00189 {
00190 return e->get_user_flag(VSOL_FLAG3) != 0;
00191 }
00192
00193 static bool self_loop(vtol_edge_2d_sptr& e)
00194 {
00195 vtol_vertex_sptr v1 = e->v1();
00196 vtol_vertex_sptr v2 = e->v2();
00197 bool loop = v1 == v2;
00198 return loop;
00199 }
00200
00201 static bool bridge_traverse(double angle)
00202 {
00203 double tol = 1e-3;
00204 double delta = vcl_fabs(vcl_fabs(angle)-180);
00205 return delta<tol;
00206 }
00207
00208
00209 static void untouch(vtol_one_chain_sptr& ch)
00210 {
00211 ch->unset_user_flag(VSOL_FLAG3);
00212 }
00213
00214 #if 0 // only clear(vtol_edge_2d_sptr& ) is used
00215 static void clear(vtol_one_chain_sptr& ch)
00216 {
00217 ch->unset_user_flag(VSOL_FLAG1);
00218 ch->unset_user_flag(VSOL_FLAG2);
00219 ch->unset_user_flag(VSOL_FLAG3);
00220 }
00221 #endif
00222
00223 static void touch(vtol_one_chain_sptr& ch)
00224 {
00225 ch->set_user_flag(VSOL_FLAG3);
00226 }
00227
00228 static bool touched(vtol_one_chain_sptr& ch)
00229 {
00230 return ch->get_user_flag(VSOL_FLAG3) != 0;
00231 }
00232
00233
00234
00235
00236
00237
00238
00239 static void v_edges(vtol_vertex_sptr v, vcl_vector<vtol_edge_2d_sptr>& b_edges,
00240 bool force, vcl_vector<vtol_edge_2d_sptr>& edges_at_vertex)
00241 {
00242 edges_at_vertex.clear();
00243 edge_list edges; v->edges(edges);
00244 for (edge_list::iterator eit = edges.begin(); eit != edges.end(); ++eit)
00245 {
00246 vtol_edge_2d_sptr e = (*eit)->cast_to_edge_2d();
00247 if (vcl_find(b_edges.begin(), b_edges.end(),e) != b_edges.end())
00248 {
00249 if (used(e))
00250 continue;
00251 if (unused(e))
00252 edges_at_vertex.push_back(e);
00253 if (half_used(e)&&force)
00254 edges_at_vertex.push_back(e);
00255 }
00256 }
00257 }
00258
00259 inline static double flip_y(double ang)
00260 {
00261
00262 ang = vcl_fmod(ang,360.0);
00263 if (ang <= 0) ang += 360.0;
00264 return 360.0-ang;
00265 }
00266
00267 static double tangent_angle_at_vertex(vtol_vertex_sptr v, vtol_edge_2d_sptr e)
00268 {
00269 double ang = 0;
00270 if (!e||!v||!(v==e->v1()||v==e->v2()))
00271 {
00272 vcl_cout << "vtol_vertex and vtol_edge not incident\n";
00273 return ang;
00274 }
00275
00276 if (v==e->v1())
00277 {
00278 ang = e->curve()->cast_to_vdgl_digital_curve()->
00279 get_interpolator()->get_tangent_angle(0);
00280 }
00281 else
00282 {
00283 int N = e->curve()->cast_to_vdgl_digital_curve()->
00284 get_interpolator()->get_edgel_chain()->size();
00285
00286 ang = e->curve()->cast_to_vdgl_digital_curve()->
00287 get_interpolator()->get_tangent_angle(N-1);
00288
00289 ang += 180.0;
00290 }
00291
00292
00293 return flip_y(ang);
00294 }
00295
00296
00297
00298 static vtol_vertex_sptr common_vertex(vtol_edge_2d_sptr& e0, vtol_edge_2d_sptr& e1)
00299 {
00300 vtol_vertex_sptr v01 = e0->v1(), v02 = e0->v2();
00301 vtol_vertex_sptr v11 = e1->v1(), v12 = e1->v2();
00302 if ((vtol_vertex_sptr)v01==(vtol_vertex_sptr)v11)
00303 return v01;
00304 if ((vtol_vertex_sptr)v01==(vtol_vertex_sptr)v12)
00305 return v01;
00306 if ((vtol_vertex_sptr)v02==(vtol_vertex_sptr)v11)
00307 return v02;
00308 if ((vtol_vertex_sptr)v02==(vtol_vertex_sptr)v12)
00309 return v02;
00310 return NULL;
00311 }
00312
00313
00314
00315
00316
00317
00318 double vtol_cycle_processor::angle_between_edges(vtol_edge_2d_sptr e0,
00319 vtol_edge_2d_sptr e1,
00320 vtol_vertex_sptr v)
00321 {
00322 double theta0 = 180+tangent_angle_at_vertex(v, e0);
00323 if (theta0>360)
00324 theta0 -= 360;
00325 double theta1 = tangent_angle_at_vertex(v, e1);
00326 double angle = theta1-theta0;
00327 if (angle>180)
00328 angle-=360;
00329 if (angle<-180)
00330 angle+=360;
00331 return angle;
00332 }
00333
00334
00335
00336
00337 static vtol_edge_2d_sptr ccw_edge(vtol_edge_2d_sptr in_edg, vtol_vertex_sptr from,
00338 vcl_vector<vtol_edge_2d_sptr>& edges)
00339 {
00340 double most_ccw = -360;
00341 vtol_edge_2d_sptr ccw = NULL;
00342 for (vcl_vector<vtol_edge_2d_sptr>::iterator eit = edges.begin();
00343 eit != edges.end(); ++eit)
00344 {
00345 if ((*eit)==in_edg)
00346 continue;
00347 double delta = vtol_cycle_processor::angle_between_edges(in_edg, *eit, from);
00348 if (delta>most_ccw)
00349 {
00350 most_ccw = delta;
00351 ccw = *eit;
00352 }
00353 }
00354
00355 if (!ccw && vcl_find(edges.begin(), edges.end(),in_edg) != edges.end())
00356 ccw = in_edg;
00357 return ccw;
00358 }
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368 bool vtol_cycle_processor::assignable(vtol_edge_2d_sptr edg, vtol_vertex_sptr last)
00369 {
00370 if (debug2_)
00371 {
00372 vcl_cout << "In assignable(..)\n"
00373 << "edg " ; this->print_edge(edg);
00374 vcl_cout << "plus used(" << plus_used(edg) << ") minus used("
00375 << minus_used(edg) << ")\n"
00376 << "last " << *last << vcl_endl;
00377 }
00378 if (!edg||!last)
00379 return false;
00380 if (unused(edg))
00381 return true;
00382 if (used(edg))
00383 return false;
00384 vtol_vertex_sptr s = edg->v1();
00385 vtol_vertex_sptr e = edg->v2();
00386 if (last==s&&!plus_used(edg))
00387 return true;
00388 if (last==e&&!minus_used(edg))
00389 return true;
00390 return false;
00391 }
00392
00393
00394
00395
00396
00397
00398
00399 void vtol_cycle_processor::assign_initial_edge(vtol_edge_2d_sptr& e,
00400 vtol_vertex_sptr& first,
00401 vtol_vertex_sptr& last)
00402 {
00403 if (debug1_)
00404 vcl_cout << "==== entering assign_initial_edge =====\n"
00405 << "e " << *e << "plus used(" << plus_used(e) << ") minus used("
00406 << minus_used(e) << ")\n";
00407
00408 if (used(e))
00409 {
00410 vcl_cout << "In vtol_cycle_processor::assign_intial_edge(..) "
00411 << "shouldn't happen - error\n";
00412 return;
00413 }
00414 vtol_vertex_sptr v1 = e->v1(), v2 = e->v2();
00415 if (v1==v2)
00416 {
00417 use_plus(e);
00418 use_minus(e);
00419 first = v1; last = v1;
00420 }
00421 if (plus_used(e))
00422 {
00423 use_minus(e);
00424 first = v2;
00425 last = v1;
00426 }
00427 else
00428 {
00429 use_plus(e);
00430 first = v1;
00431 last = v2;
00432 }
00433 if (debug1_)
00434 vcl_cout << "==== leaving assign_initial_edge =====\n"
00435 << "plus used(" << plus_used(e) << ") minus used("
00436 << minus_used(e) << ")\n\n";
00437 }
00438
00439
00440
00441
00442
00443 void vtol_cycle_processor::assign_ends(vtol_edge_2d_sptr edg, vtol_vertex_sptr& last)
00444 {
00445 if (debug1_)
00446 vcl_cout << "==== entering assign_ends =====\n"
00447 << "edg " << *edg << "plus used(" << plus_used(edg) << ") minus used("
00448 << minus_used(edg) << ")\n";
00449 vtol_vertex_sptr s = edg->v1();
00450 vtol_vertex_sptr e = edg->v2();
00451
00452
00453
00454 if (last == s)
00455 {
00456 last = e;
00457 use_plus(edg);
00458 if (s==e)
00459 use_minus(edg);
00460 return;
00461 }
00462 if (last == e)
00463 {
00464 last = s;
00465 use_minus(edg);
00466 if (s==e)
00467 use_plus(edg);
00468 return;
00469 }
00470 vcl_cout << "In vtol_cycle_processor::assign ends(..) - shouldn't happen\n";
00471 }
00472
00473
00474
00475
00476
00477
00478
00479 static void assign_stack_edge(vcl_vector<vtol_edge_2d_sptr>& e_stack, vtol_edge_2d_sptr& next_edge)
00480 {
00481 if (!e_stack.size())
00482 return;
00483 next_edge = e_stack.back();
00484 }
00485
00486
00487
00488
00489
00490 void vtol_cycle_processor::init(vcl_vector<vtol_edge_2d_sptr>& in_edges)
00491 {
00492 edges_.clear();
00493 chains_.clear();
00494 nested_one_cycles_.clear();
00495 for (vcl_vector<vtol_edge_2d_sptr>::iterator eit = in_edges.begin();
00496 eit != in_edges.end(); ++eit)
00497 {
00498 clear(*eit);
00499 edges_.push_back(*eit);
00500 }
00501 this->set_bridge_vars();
00502 valid_ = false;
00503 }
00504
00505
00506
00507
00508
00509 void vtol_cycle_processor::set_bridge_vars()
00510 {
00511 if (!edges_.size())
00512 return;
00513 v_stack_.clear();
00514 e_stack_.clear();
00515 l_ = edges_[0];
00516 e_stack_.push_back(l_);
00517 assign_initial_edge(l_, first_, last_);
00518 cycle_ = first_==last_;
00519 found_next_edge_ = true;
00520 v_stack_.push_back(last_);
00521 if (!cycle_)
00522 v_stack_.push_back(first_);
00523 else
00524 touch(l_);
00525 if (debug1_)
00526 {
00527 vcl_cout << "------init bridge vars-------\n"
00528 << "oooooooo Vertex Stack ooooooooo\n";
00529 print_vertices(v_stack_);
00530 vcl_cout << "oooooooo Edge Stack ooooooooo\n";
00531 print_edges(e_stack_);
00532 }
00533 }
00534
00535
00536
00537
00538
00539 static void classify_adjacent_edges(vtol_edge_2d_sptr& e0, vtol_edge_2d_sptr& e1,
00540 bool& all_bridge, double& angle)
00541 {
00542 vtol_vertex_sptr cv = common_vertex(e0, e1);
00543 if (cv)
00544 {
00545 angle = vtol_cycle_processor::angle_between_edges(e0, e1, cv);
00546 all_bridge = all_bridge && used(e1) && bridge_traverse(angle);
00547 }
00548 }
00549
00550
00551
00552
00553
00554 static bool classify_two_edge_path(vtol_edge_2d_sptr& e0, vtol_edge_2d_sptr& e1)
00555 {
00556 vtol_vertex_sptr v1 = e0->v1(), v2 = e0->v1();
00557 double angle1 = vtol_cycle_processor::angle_between_edges(e0, e1, v1);
00558 double angle2 = vtol_cycle_processor::angle_between_edges(e0, e1, v2);
00559 bool bridge = bridge_traverse(angle1)&&bridge_traverse(angle2);
00560 return !bridge;
00561 }
00562
00563
00564
00565
00566
00567
00568 vtol_edge_2d_sptr vtol_cycle_processor::search_for_next_edge(vcl_vector<vtol_edge_2d_sptr>& edges_at_last)
00569 {
00570 while (edges_at_last.size())
00571 {
00572 vtol_edge_2d_sptr temp = ccw_edge(l_, last_, edges_at_last);
00573 if (debug2_)
00574 {
00575 vcl_cout << "next ccw_edge\n";
00576 this->print_edge(temp);
00577 }
00578 if (!temp || assignable(temp, last_))
00579 return temp;
00580 edge_2d_erase(edges_at_last, temp);
00581 }
00582 return NULL;
00583 }
00584
00585
00586
00587
00588 void vtol_cycle_processor::add_edge_to_path()
00589 {
00590 vtol_vertex_sptr temp = last_;
00591 assign_ends(next_edge_, temp);
00592 if (debug2_)
00593 vcl_cout << "==== after assign_ends =====\n"
00594 << "next_edge_ " << *next_edge_ << "plus used("
00595 << plus_used(next_edge_) << ") minus used("
00596 << minus_used(next_edge_) << ")\n\n";
00597 v_stack_.push_back(last_);
00598 last_ = temp;
00599 l_ = next_edge_;
00600 e_stack_.push_back(l_);
00601 touch(l_);
00602 if (debug1_)
00603 {
00604 vcl_cout << "------assign_edge_to_path-------\n"
00605 << "oooooooo Vertex Stack ooooooooo\n";
00606 print_vertices(v_stack_);
00607 vcl_cout << "oooooooo Edge Stack ooooooooo\n";
00608 print_edges(e_stack_);
00609 }
00610 }
00611
00612
00613
00614
00615
00616
00617
00618 bool vtol_cycle_processor::classify_path(vcl_vector<vtol_edge_2d_sptr>& path_edges,
00619 vtol_one_chain_sptr& chain)
00620 {
00621 if (debug1_)
00622 vcl_cout << "======= In classify_path ========\n";
00623 if (!path_edges.size())
00624 return false;
00625 edge_list c_edges;
00626 vtol_edge_2d_sptr e0 = *path_edges.begin();
00627
00628
00629 if (self_loop(e0))
00630 {
00631 c_edges.push_back(e0->cast_to_edge());
00632 chain = new vtol_one_chain(c_edges, true);
00633 set_ccw(chain); set_cw(chain);
00634 return true;
00635 }
00636
00637
00638 double winding_angle = 0, angle = 0;
00639 bool all_bridge = used(e0);
00640
00641
00642 if (path_edges.size()==2)
00643 if (classify_two_edge_path(e0, *(path_edges.begin()+1)))
00644 {
00645 c_edges.push_back(e0->cast_to_edge());
00646 chain = new vtol_one_chain(c_edges, true);
00647 set_ccw(chain); set_cw(chain);
00648 return true;
00649 }
00650
00651 for (vcl_vector<vtol_edge_2d_sptr>::iterator eit = path_edges.begin()+1;
00652 eit != path_edges.end(); ++eit)
00653 {
00654 classify_adjacent_edges(e0, *eit, all_bridge, angle);
00655
00656 if (debug1_)
00657 vcl_cout << "wind_ang " << winding_angle << " - " << angle << " = "
00658 << winding_angle - angle << vcl_endl;
00659
00660 winding_angle -= angle;
00661
00662 e0 = *eit;
00663 }
00664 vtol_edge_2d_sptr eN = *path_edges.begin();
00665 classify_adjacent_edges(e0, eN, all_bridge, angle);
00666 winding_angle -= angle;
00667
00668 if (all_bridge)
00669 return false;
00670
00671 for (vcl_vector<vtol_edge_2d_sptr>::iterator eit = path_edges.begin();
00672 eit != path_edges.end(); ++eit)
00673 c_edges.push_back((*eit)->cast_to_edge());
00674
00675 chain = new vtol_one_chain(c_edges, true);
00676
00677 if (winding_angle>0)
00678 set_ccw(chain);
00679 else
00680 set_cw(chain);
00681 return true;
00682 }
00683
00684 void vtol_cycle_processor::print_edge(vtol_edge_2d_sptr& e)
00685 {
00686 if (!e)
00687 return;
00688 vcl_cout << e << " :[(" << e->v1()->cast_to_vertex_2d()->x()
00689 << ' ' << e->v1()->cast_to_vertex_2d()->y()<< "), ("
00690 << e->v2()->cast_to_vertex_2d()->x() << ' '
00691 << e->v2()->cast_to_vertex_2d()->y() << ")]\n";
00692 }
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720 void vtol_cycle_processor::compute_cycles()
00721 {
00722 int limit = 10*edges_.size();
00723 while (edges_.size()&&limit--)
00724 if (found_next_edge_&&!cycle_)
00725 {
00726 bool force = false;
00727
00728 if (debug1_&&last_) {
00729 vcl_cout << "last_ ="; last_->print(); vcl_cout <<vcl_endl;
00730 }
00731
00732 vcl_vector<vtol_edge_2d_sptr> edges_at_last;
00733 v_edges(last_, edges_, force, edges_at_last);
00734 next_edge_ = search_for_next_edge(edges_at_last);
00735
00736 if (!next_edge_&&!force)
00737 {
00738 force = true;
00739 v_edges(last_, edges_, force, edges_at_last);
00740 next_edge_ = search_for_next_edge(edges_at_last);
00741 }
00742 if (debug1_&&next_edge_) {
00743 vcl_cout << "next_edge_("<< force <<") = "; this->print_edge(next_edge_);
00744 }
00745
00746 if (!next_edge_)
00747 found_next_edge_ = false;
00748 else
00749 add_edge_to_path();
00750 if (debug1_)
00751 vcl_cout << "========checking for cycle ===========\n"
00752 << " last_ " << last_ << '('
00753 << last_->cast_to_vertex_2d()->x()<< ' '
00754 << last_->cast_to_vertex_2d()->y()<< ")\n";
00755 cycle_ = vcl_find(v_stack_.begin(), v_stack_.end(), last_) != v_stack_.end();
00756 if (debug1_&&cycle_)
00757 vcl_cout << "...Found Cycle....\n\n";
00758 }
00759 else
00760 {
00761 if (cycle_)
00762 {
00763 cycle_ = false;
00764 vcl_vector<vtol_edge_2d_sptr> cycle_edges;
00765 pop_stacks(v_stack_, e_stack_, last_, cycle_edges);
00766 if (debug1_)
00767 {
00768 vcl_cout << "======== In Cycle Classifier =======\n"
00769 << "cycle_edges\n";
00770 print_edges(cycle_edges);
00771 }
00772 assign_stack_edge(e_stack_, l_);
00773 vtol_one_chain_sptr cycle;
00774 bool is_cycle = classify_path(cycle_edges, cycle);
00775 if (debug1_)
00776 {
00777 vcl_cout << "is_cycle(" << is_cycle << ")\n";
00778 if (cycle)
00779 {
00780 vcl_cout << "cycle " << cycle << "[cw(" << cw(cycle)
00781 << "), ccw(" << ccw(cycle) << ")]\n";
00782 vcl_vector<vtol_edge_sptr> c_edges; cycle->edges(c_edges);
00783 vcl_cout << "cycle edges\n";
00784 print_edges(c_edges);
00785 }
00786 }
00787 if (is_cycle)
00788 chains_.push_back(cycle);
00789 else
00790 for (vcl_vector<vtol_edge_2d_sptr>::iterator eit = cycle_edges.begin();
00791 eit != cycle_edges.end(); ++eit)
00792 edge_2d_erase(edges_,*eit);
00793 }
00794 if (!found_next_edge_)
00795 {
00796
00797 vcl_vector<vtol_edge_2d_sptr> removed_edges;
00798 for (vcl_vector<vtol_edge_2d_sptr>::iterator eit = edges_.begin();
00799 eit != edges_.end(); ++eit)
00800 if (touched(*eit)&&used(*eit))
00801 removed_edges.push_back(*eit);
00802 for (vcl_vector<vtol_edge_2d_sptr>::iterator
00803 eit = removed_edges.begin(); eit != removed_edges.end();
00804 ++eit)
00805 edge_2d_erase(edges_,*eit);
00806
00807 this->set_bridge_vars();
00808 }
00809 }
00810 if (!limit)
00811 vcl_cout << "Limit Exhaused in vtol_cycle_processor::compute_cycles(..)\n";
00812 }
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822 void vtol_cycle_processor::sort_one_cycles()
00823 {
00824 if (!chains_.size())
00825 {
00826 vcl_cout << "In vtol_cycle_processor::sort_one_cycles(..) no cycles\n";
00827 return;
00828 }
00829 nested_one_cycles_.clear();
00830
00831
00832
00833 double area = 0;
00834 vtol_one_chain_sptr outer_chain = 0;
00835 for (one_chain_list::iterator cit=chains_.begin(); cit!=chains_.end(); ++cit)
00836 {
00837 untouch(*cit);
00838 if (!ccw(*cit))
00839 continue;
00840 vsol_box_2d_sptr box = (*cit)->get_bounding_box();
00841 double WxH = box->width()*box->height();
00842 if (WxH>area)
00843 {
00844 area = WxH;
00845 outer_chain = *cit;
00846 }
00847 }
00848
00849 if (!outer_chain||!ccw(outer_chain))
00850 {
00851 vcl_cout << "In vtol_cycle_processor::sort_one_cycles(..)"
00852 << " Shouldn't happen that there is no outer chain\n"
00853 << "N cycles = " << chains_.size() << vcl_endl;
00854 for (one_chain_list::iterator cit = chains_.begin();
00855 cit != chains_.end(); ++cit)
00856 {
00857 vcl_cout << " chain is " << (ccw(*cit) ? "" : "not ") << "ccw, "
00858 << "chain is " << (cw(*cit) ? "" : "not ") << "cw\n";
00859 }
00860 vcl_cout << "Outer Chain " << outer_chain << vcl_endl;
00861 return;
00862 }
00863 nested_one_cycles_.push_back(outer_chain);
00864 touch(outer_chain);
00865 if (debug1_)
00866 vcl_cout << "Outer Cycle area = " << area << vcl_endl;
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877 vsol_box_2d_sptr b = outer_chain->get_bounding_box();
00878 for (one_chain_list::iterator cit=chains_.begin(); cit!=chains_.end(); ++cit)
00879 if (cw(*cit)&&!touched(*cit))
00880 {
00881 if ((*cit)==outer_chain)
00882 continue;
00883 vsol_box_2d_sptr bc = (*cit)->get_bounding_box();
00884 if ((*bc<*b)&&!bc->near_equal(*b, tolerance_))
00885 {
00886 vsol_box_2d_sptr bc = (*cit)->get_bounding_box();
00887 if ((*bc<*b)&&!bc->near_equal(*b, tolerance_))
00888 {
00889 if (debug1_)
00890 vcl_cout << "Adding inner cycle with area = "
00891 << bc->width()*bc->height() << vcl_endl;
00892
00893 nested_one_cycles_.push_back(*cit);
00894 touch(*cit);
00895 }
00896 }
00897 }
00898 }
00899
00900 void vtol_cycle_processor::process()
00901 {
00902 this->compute_cycles();
00903 this->sort_one_cycles();
00904 valid_ = true;
00905 }
00906
00907 bool vtol_cycle_processor::nested_one_cycles(one_chain_list& one_chains,
00908 const float& tolerance)
00909 {
00910 if (!valid_||tolerance!=tolerance_)
00911 {
00912 tolerance_ = tolerance;
00913 process();
00914 }
00915 one_chains = nested_one_cycles_;
00916 return true;
00917 }
00918
00919
00920 static void clear_flags(vcl_vector<vtol_edge_sptr>& s, unsigned int flag)
00921 {
00922 for (vcl_vector<vtol_edge_sptr>::iterator eit = s.begin();
00923 eit != s.end(); ++eit)
00924 (*eit)->unset_user_flag(flag);
00925 }
00926
00927 static void set_flags(vcl_vector<vtol_edge_sptr>& s, unsigned int flag)
00928 {
00929 for (vcl_vector<vtol_edge_sptr>::iterator eit = s.begin();
00930 eit != s.end(); ++eit)
00931 (*eit)->set_user_flag(flag);
00932 }
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943 bool vtol_cycle_processor::intersect_edges(vcl_vector<vtol_edge_sptr>& s1,
00944 vcl_vector<vtol_edge_sptr>& s2,
00945 vcl_vector<vtol_edge_sptr>& s1_and_s2)
00946 {
00947 s1_and_s2.clear();
00948
00949 if (!(s1.size()&&s2.size()))
00950 return false;
00951
00952 unsigned int flag1 = VSOL_FLAG5, flag2 = VSOL_FLAG6;
00953
00954 clear_flags(s2, flag1);
00955 clear_flags(s2, flag2);
00956
00957
00958
00959 set_flags(s1, flag1);
00960
00961
00962
00963 for (vcl_vector<vtol_edge_sptr>::iterator eit = s2.begin();
00964 eit != s2.end(); ++eit)
00965 {
00966 vtol_edge_sptr e = *eit;
00967 if (e->get_user_flag(flag1)&&!e->get_user_flag(flag2))
00968 {
00969 e->set_user_flag(flag2);
00970 s1_and_s2.push_back(e);
00971 }
00972 }
00973
00974 clear_flags(s1, flag1);
00975 clear_flags(s2, flag1);
00976 clear_flags(s1, flag2);
00977 clear_flags(s2, flag2);
00978 return s1_and_s2.size()>0;
00979 }
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990 bool vtol_cycle_processor::difference_edges(vcl_vector<vtol_edge_sptr>& s1,
00991 vcl_vector<vtol_edge_sptr>& s2,
00992 vcl_vector<vtol_edge_sptr>& s1_minus_s2)
00993 {
00994 s1_minus_s2.clear();
00995
00996 if (!(s1.size()&&s2.size()))
00997 return false;
00998
00999 unsigned int flag1 = VSOL_FLAG5, flag2 = VSOL_FLAG6;
01000
01001 clear_flags(s1, flag1);
01002 clear_flags(s1, flag2);
01003
01004
01005 set_flags(s2, flag1);
01006
01007
01008
01009 for (vcl_vector<vtol_edge_sptr>::iterator eit = s1.begin();
01010 eit != s1.end(); ++eit)
01011 {
01012 vtol_edge_sptr e = *eit;
01013 if (!e->get_user_flag(flag1)&&!e->get_user_flag(flag2))
01014 {
01015 e->set_user_flag(flag2);
01016 s1_minus_s2.push_back(e);
01017 }
01018 }
01019
01020 clear_flags(s1, flag1);
01021 clear_flags(s2, flag1);
01022 clear_flags(s1, flag2);
01023 clear_flags(s2, flag2);
01024 return s1_minus_s2.size()>0;
01025 }
01026
01027
01028
01029
01030 bool vtol_cycle_processor::corrupt_boundary(vcl_vector<vtol_edge_2d_sptr>& edges,
01031 vcl_vector<vtol_vertex_sptr>& bad_verts)
01032 {
01033 bool bad = false;
01034
01035 if (!edges.front())
01036 {
01037 vcl_cout << "In cycle_processor::corrupt_boundary - null edge\n";
01038 return false;
01039 }
01040
01041 unsigned int f1=VSOL_FLAG4, f2=VSOL_FLAG5, f3=VSOL_FLAG6;
01042
01043 for (vcl_vector<vtol_edge_2d_sptr>::iterator eit = edges.begin();
01044 eit != edges.end(); ++eit)
01045 {
01046 vtol_vertex_sptr v1 = (*eit)->v1();
01047 vtol_vertex_sptr v2 = (*eit)->v2();
01048 v1->unset_user_flag(f1);
01049 v1->unset_user_flag(f2);
01050 v1->unset_user_flag(f3);
01051 v2->unset_user_flag(f1);
01052 v2->unset_user_flag(f2);
01053 v2->unset_user_flag(f3);
01054 }
01055
01056
01057 for (vcl_vector<vtol_edge_2d_sptr>::iterator eit = edges.begin();
01058 eit != edges.end(); ++eit)
01059 {
01060 vtol_vertex_sptr v1 = (*eit)->v1();
01061 vtol_vertex_sptr v2 = (*eit)->v2();
01062 if (!v1->get_user_flag(f1))
01063 v1->set_user_flag(f1);
01064 else
01065 v1->set_user_flag(f2);
01066 if (!v2->get_user_flag(f1))
01067 v2->set_user_flag(f1);
01068 else
01069 v2->set_user_flag(f2);
01070 }
01071 for (vcl_vector<vtol_edge_2d_sptr>::iterator eit = edges.begin();
01072 eit != edges.end(); ++eit)
01073 {
01074 vtol_vertex_sptr v1 = (*eit)->v1();
01075 vtol_vertex_sptr v2 = (*eit)->v2();
01076 if ((v1!=v2)&&*v1==*v2)
01077 vcl_cout << "Improper Loop(\n" << *v1 << *v2 << ")\n\n";
01078 bool bad1 = !v1->get_user_flag(f2);
01079 bool bad2 = !v2->get_user_flag(f2);
01080
01081 if (bad1)
01082 {
01083 if (!v1->get_user_flag(f3))
01084 {
01085 bad_verts.push_back(v1);
01086 v1->set_user_flag(f3);
01087 }
01088 bad = true;
01089 }
01090 if (bad2)
01091 {
01092 if (!v2->get_user_flag(f3))
01093 {
01094 bad_verts.push_back(v2);
01095 v2->set_user_flag(f3);
01096 }
01097 bad = true;
01098 }
01099 }
01100
01101 for (vcl_vector<vtol_edge_2d_sptr>::iterator eit = edges.begin();
01102 eit != edges.end(); ++eit)
01103 {
01104 vtol_vertex_sptr v1 = (*eit)->v1();
01105 vtol_vertex_sptr v2 = (*eit)->v2();
01106 v1->unset_user_flag(f1);
01107 v1->unset_user_flag(f2);
01108 v1->unset_user_flag(f3);
01109 v2->unset_user_flag(f1);
01110 v2->unset_user_flag(f2);
01111 v2->unset_user_flag(f3);
01112 }
01113 return bad;
01114 }
01115
01116
01117
01118
01119
01120
01121
01122
01123 bool vtol_cycle_processor::connect_paths(vcl_vector<vtol_edge_2d_sptr>& edges,
01124 vcl_vector<vtol_vertex_sptr>& bad_verts)
01125 {
01126 bool paths_connected = true;
01127 if (!bad_verts.size())
01128 return paths_connected;
01129
01130
01131
01132
01133
01134 vcl_vector<vtol_vertex_sptr> temp;
01135
01136
01137
01138
01139
01140
01141 unsigned int flag1 = VSOL_FLAG5, flag2=VSOL_FLAG6;
01142
01143 if (!bad_verts.front())
01144 return false;
01145
01146 for (vcl_vector<vtol_vertex_sptr>::iterator vit = bad_verts.begin();
01147 vit != bad_verts.end(); ++vit)
01148 {
01149 (*vit)->unset_user_flag(flag1);
01150 temp.push_back(*vit);
01151 }
01152
01153
01154 for (vcl_vector<vtol_edge_2d_sptr>::iterator eit = edges.begin();
01155 eit != edges.end(); ++eit)
01156 {
01157 vtol_vertex_sptr v1 = (*eit)->v1(), v2 = (*eit)->v2();
01158 v1->unset_user_flag(flag1); v2->unset_user_flag(flag1);
01159 v1->unset_user_flag(flag2); v2->unset_user_flag(flag2);
01160 }
01161
01162
01163 vcl_vector<vtol_vertex_sptr> edge_verts;
01164 for (vcl_vector<vtol_edge_2d_sptr>::iterator eit = edges.begin();
01165 eit != edges.end(); ++eit)
01166 {
01167 vtol_vertex_sptr v1 = (*eit)->v1(), v2 = (*eit)->v2();
01168 if (!v1->get_user_flag(flag1))
01169 {edge_verts.push_back(v1); v1->set_user_flag(flag1);}
01170 if (!v2->get_user_flag(flag1))
01171 {edge_verts.push_back(v2); v2->set_user_flag(flag1);}
01172 }
01173
01174
01175
01176
01177 vcl_vector<vtol_vertex_sptr> repaired_verts;
01178 for (vcl_vector<vtol_vertex_sptr>::iterator vit=bad_verts.begin();
01179 vit != bad_verts.end(); ++vit)
01180 {
01181 if ((*vit)->get_user_flag(flag2))
01182 continue;
01183 bool found_edge = false;
01184
01185 vcl_vector<vtol_edge_sptr> vedges; (*vit)->edges(vedges);
01186
01187 for (vcl_vector<vtol_edge_sptr>::iterator eit = vedges.begin();
01188 eit != vedges.end()&&!found_edge; ++eit)
01189 {
01190 vtol_edge_2d_sptr e = (*eit)->cast_to_edge_2d();
01191 vtol_vertex_sptr v = (*eit)->other_endpoint(*(*vit));
01192
01193
01194
01195
01196
01197
01198 if (!e)
01199 continue;
01200 if (v->get_user_flag(flag2))
01201 continue;
01202 bool found_in_bad_verts = vcl_find(temp.begin(),temp.end(),v) != temp.end();
01203 bool found_in_edge_verts = false;
01204 if (!found_in_bad_verts)
01205 found_in_edge_verts = vcl_find(edge_verts.begin(),edge_verts.end(),v) != edge_verts.end();
01206 if (!found_in_bad_verts && !found_in_edge_verts)
01207 continue;
01208 if ( vcl_find(edges.begin(),edges.end(),e) != edges.end())
01209 continue;
01210
01211
01212 edges.push_back(e);
01213 found_edge = true;
01214 v->set_user_flag(flag2);
01215 (*vit)->set_user_flag(flag2);
01216
01217 repaired_verts.push_back(*vit);
01218 repaired_verts.push_back(v);
01219 }
01220 paths_connected =
01221 paths_connected&&(*vit)->get_user_flag(flag2);
01222 }
01223
01224 for (vcl_vector<vtol_vertex_sptr>::iterator vit = bad_verts.begin();
01225 vit!=bad_verts.end(); ++vit)
01226 {
01227 (*vit)->unset_user_flag(flag1);
01228 (*vit)->unset_user_flag(flag2);
01229 }
01230 for (vcl_vector<vtol_vertex_sptr>::iterator vit = edge_verts.begin();
01231 vit!=edge_verts.end(); ++vit)
01232 {
01233 (*vit)->unset_user_flag(flag1);
01234 (*vit)->unset_user_flag(flag2);
01235 }
01236
01237 for (vcl_vector<vtol_vertex_sptr>::iterator vit = repaired_verts.begin();
01238 vit != repaired_verts.end(); ++vit)
01239 {
01240 vcl_vector<vtol_vertex_sptr>::iterator erit;
01241 erit = vcl_find(bad_verts.begin(), bad_verts.end(), *vit);
01242 if (erit != bad_verts.end())
01243 bad_verts.erase(erit);
01244 }
01245 return paths_connected;
01246 }