00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 #define ACG_MESHEDGESAMPLERT_C
00051
00052
00053
00054 #include "MeshEdgeSamplerT.hh"
00055 #include <math.h>
00056 #include <float.h>
00057 #include <map>
00058 #include "../Algorithms.hh"
00059
00060
00061
00062
00063
00064
00065
00066 namespace ACG {
00067
00068
00069
00070
00071 template <class MeshT, class PointT>
00072 void
00073 MeshEdgeSamplerT<MeshT, PointT>::
00074 edge_points_in_segment( const PointT& _p_start,
00075 const PointT& _p_end,
00076 const FH _fh_start,
00077 const FH _fh_end,
00078 std::vector<PointT>& _points,
00079 std::vector<EH>& _ehandles )
00080 {
00081
00082 _points.clear();
00083 _ehandles.clear();
00084
00085 #ifdef MES_DEBUG_HELPER
00086
00087
00088 mesh_.status(_fh_start).set_selected(true);
00089 mesh_.status(_fh_end).set_selected(true);
00090
00091 #endif
00092
00093
00094 if(_fh_start == _fh_end)
00095 return;
00096
00097
00098 std::vector<FH> endfhs;
00099 get_end_fhs_set( _p_end, _fh_end, endfhs);
00100
00101
00102 std::vector<Point> new_points0;
00103 std::vector<Point> new_points1;
00104 std::vector<EH> new_ehs0;
00105 std::vector<EH> new_ehs1;
00106
00107
00108 HEH cur_heh0, cur_heh1;
00109 FH cur_fh0, cur_fh1;
00110
00111
00112 if( std::find(endfhs.begin(), endfhs.end(), _fh_start) != endfhs.end())
00113 {
00114
00115 Point p_best;
00116 double d_best = FLT_MAX;
00117
00118
00119 typename Mesh::FHIter fh_it = mesh_.fh_iter(_fh_start);
00120 for(; fh_it; ++fh_it)
00121 {
00122 FH cur_fh = mesh_.opposite_face_handle(fh_it.handle());
00123 if( std::find(endfhs.begin(), endfhs.end(), cur_fh) != endfhs.end())
00124 {
00125 Point p_new;
00126 double d_new = line_line_dist(_p_start, _p_end, fh_it.handle(), p_new);
00127 if( d_new < d_best)
00128 {
00129 d_best = d_new;
00130 p_best = p_new;
00131 cur_heh0 = fh_it.handle();
00132 cur_heh1 = fh_it.handle();
00133 cur_fh0 = mesh_.opposite_face_handle( cur_heh0);
00134 cur_fh1 = mesh_.opposite_face_handle( cur_heh1);
00135 }
00136 }
00137 }
00138
00139
00140 new_points0.push_back(p_best);
00141 new_points1.push_back(p_best);
00142 new_ehs0.push_back( mesh_.edge_handle( cur_heh0));
00143 new_ehs1.push_back( mesh_.edge_handle( cur_heh1));
00144 }
00145 else
00146 {
00147
00148 compute_plane( _p_start, _p_end, _fh_start, _fh_end);
00149
00150
00151 get_start_hehs( _p_start, _fh_start, cur_heh0, cur_heh1);
00152
00153
00154
00155
00156
00157 Point p_int;
00158
00159 plane_line_intersection( cur_heh0, p_int);
00160 new_points0.push_back( p_int);
00161 new_ehs0.push_back( mesh_.edge_handle( cur_heh0));
00162
00163 plane_line_intersection( cur_heh1, p_int);
00164 new_points1.push_back( p_int);
00165 new_ehs1.push_back( mesh_.edge_handle( cur_heh1));
00166
00167
00168 cur_fh0 = mesh_.face_handle( mesh_.opposite_halfedge_handle(cur_heh0));
00169 cur_fh1 = mesh_.face_handle( mesh_.opposite_halfedge_handle(cur_heh1));
00170
00171
00172 int steps = 0;
00173 while( std::find(endfhs.begin(), endfhs.end(), cur_fh0) == endfhs.end() &&
00174 std::find(endfhs.begin(), endfhs.end(), cur_fh1) == endfhs.end() &&
00175 steps < 2000 )
00176 {
00177
00178 ++steps;
00179
00180
00181 cur_heh0 = get_next_edge_intersection( cur_heh0, new_points0.back(), p_int);
00182 new_points0.push_back( p_int);
00183 new_ehs0.push_back( mesh_.edge_handle( cur_heh0));
00184
00185
00186 cur_heh1 = get_next_edge_intersection( cur_heh1, new_points1.back(), p_int);
00187 new_points1.push_back( p_int);
00188 new_ehs1.push_back( mesh_.edge_handle( cur_heh1));
00189
00190
00191 cur_fh0 = mesh_.face_handle(mesh_.opposite_halfedge_handle(cur_heh0));
00192 cur_fh1 = mesh_.face_handle(mesh_.opposite_halfedge_handle(cur_heh1));
00193
00194
00195 if(!cur_fh0.is_valid() || !cur_heh1.is_valid())
00196 {
00197 std::cerr << "ERROR (MeshEdgeSamplerT): face handle not valid (possibly hit boundary)\n";
00198 break;
00199 }
00200 }
00201 }
00202
00203
00204
00205 if( std::find(endfhs.begin(), endfhs.end(), cur_fh0) != endfhs.end())
00206 {
00207 finish_list( new_points0, new_ehs0, cur_heh0, _fh_end, _p_end, endfhs.size());
00208
00209 _points = new_points0;
00210 _ehandles = new_ehs0;
00211 }
00212 else if( std::find(endfhs.begin(), endfhs.end(), cur_fh1) != endfhs.end())
00213 {
00214 finish_list( new_points1, new_ehs1, cur_heh1, _fh_end, _p_end, endfhs.size());
00215
00216 _points = new_points1;
00217 _ehandles = new_ehs1;
00218 }
00219 else
00220 {
00221 std::cerr << "WARNING (MeshEdgeSamplerT): Did not find FH_END\n";
00222
00223
00224 _points.clear();
00225 _ehandles.clear();
00226 }
00227
00228
00229 #ifdef MES_DEBUG_HELPER
00230
00231
00232 for(unsigned int i=0; i<_ehandles.size(); ++i)
00233 {
00234 mesh_.status( _ehandles[i]).set_selected(true);
00235
00236 #ifdef MES_DEBUG_HELPER_MOVE_ON_EDGE
00237 HEH heh0 = mesh_.halfedge_handle( _ehandles[i], 0);
00238 HEH heh1 = mesh_.halfedge_handle( _ehandles[i], 1);
00239
00240 Point p0 = mesh_.point( mesh_.to_vertex_handle(heh0));
00241 Point p1 = mesh_.point( mesh_.to_vertex_handle(heh1));
00242
00243 if( (_points[i]-p0).norm() < (_points[i]-p1).norm())
00244 _points[i] += (p1-p0)*0.25;
00245 else
00246 _points[i] -= (p1-p0)*0.25;
00247 #endif
00248 }
00249
00250 #endif
00251 }
00252
00253
00254
00255
00256
00257 template <class MeshT, class PointT>
00258 void
00259 MeshEdgeSamplerT<MeshT, PointT>::
00260 compute_plane(const PointT& _p_start,
00261 const PointT& _p_end,
00262 const FH _fh_start,
00263 const FH _fh_end )
00264 {
00265
00266
00267 HEH heh = mesh_.halfedge_handle(_fh_start);
00268 Point p0 = (Point)mesh_.point(mesh_.to_vertex_handle( heh ));
00269 Point p1 = (Point)mesh_.point(mesh_.to_vertex_handle( heh = mesh_.next_halfedge_handle(heh) ));
00270 Point p2 = (Point)mesh_.point(mesh_.to_vertex_handle( heh = mesh_.next_halfedge_handle(heh) ));
00271 Point n_start = ((p1-p0)%(p2-p0)).normalize();
00272
00273
00274 heh = mesh_.halfedge_handle(_fh_end);
00275 p0 = mesh_.point(mesh_.to_vertex_handle( heh ));
00276 p1 = mesh_.point(mesh_.to_vertex_handle( heh = mesh_.next_halfedge_handle(heh) ));
00277 p2 = mesh_.point(mesh_.to_vertex_handle( heh = mesh_.next_halfedge_handle(heh) ));
00278 Point n_end = ((p1-p0)%(p2-p0)).normalize();
00279
00280
00281 Point n_avg = n_start + n_end;
00282 if( n_avg.sqrnorm() < 1e-7) n_avg = n_start - n_end;
00283 n_avg.normalize();
00284
00285
00286 n_plane_ = n_avg % (_p_start-_p_end).normalize();
00287 if( n_plane_.sqrnorm() > 1e-8) n_plane_.normalize();
00288 else std::cerr << "WARNING: Edge Resampling -> not possible to construct stable cut plane!!!\n";
00289 p_plane_ = (_p_start + _p_end)*0.5;
00290 }
00291
00292
00293
00294
00295
00296 template <class MeshT, class PointT>
00297 void
00298 MeshEdgeSamplerT<MeshT, PointT>::
00299 get_start_hehs( const Point& ,
00300 const FH _fh_start,
00301 HEH& _sheh0,
00302 HEH& _sheh1 )
00303 {
00304
00305 HEH heh0 = mesh_.halfedge_handle( _fh_start);
00306 HEH heh1 = mesh_.next_halfedge_handle( heh0);
00307 HEH heh2 = mesh_.next_halfedge_handle( heh1);
00308
00309 Point p0 = (Point) mesh_.point(mesh_.to_vertex_handle(heh0));
00310 Point p1 = (Point) mesh_.point(mesh_.to_vertex_handle(heh1));
00311 Point p2 = (Point) mesh_.point(mesh_.to_vertex_handle(heh2));
00312
00313 double eps = 1e-5*((p1-p0).norm() + (p2-p1).norm() + (p2-p0).norm());
00314
00315
00316 if( line_in_plane( p0, p1, eps))
00317 {
00318
00319 _sheh0 = heh2;
00320 _sheh1 = heh0;
00321 }
00322 else if( line_in_plane( p1, p2, eps))
00323 {
00324
00325 _sheh0 = heh0;
00326 _sheh1 = heh1;
00327 }
00328 else if( line_in_plane( p2, p0, eps))
00329 {
00330
00331 _sheh0 = heh1;
00332 _sheh1 = heh2;
00333 }
00334
00335 else
00336 {
00337
00338 Point ip0, ip1, ip2;
00339 double d0 = plane_line_intersection(p0,p2, ip0);
00340 double d1 = plane_line_intersection(p1,p0, ip1);
00341 double d2 = plane_line_intersection(p2,p1, ip2);
00342
00343
00344 sort_intersections( heh0, d0, ip0,
00345 heh1, d1, ip1,
00346 heh2, d2, ip2 );
00347
00348
00349 if( d1 >= eps && d2 >= eps)
00350 {
00351 std::cerr << "ERROR (MeshEdgeSamplerT): Two intersections larger than epsilon...\n";
00352 _sheh0 = heh0;
00353 _sheh1 = heh1;
00354 }
00355 else if( d0 < eps && d1 < eps && d2 >= eps)
00356 {
00357
00358 _sheh0 = heh0;
00359 _sheh1 = heh1;
00360 }
00361 else if( d0 < eps && d1 < eps && d2 < eps)
00362 {
00363
00364 if( (ip0-ip1).norm() < (ip0-ip2).norm())
00365 {
00366 _sheh0 = heh0;
00367 _sheh1 = heh2;
00368 }
00369 else
00370 {
00371 _sheh0 = heh0;
00372 _sheh1 = heh1;
00373 }
00374 }
00375 else
00376 {
00377 std::cerr << "ERROR (MeshEdgeSamplerT): this state cannot be reached, what went wrong?\n";
00378 std::cerr << d0 << " " << d1 << " " << d2 << std::endl;
00379 _sheh0 = heh0;
00380 _sheh1 = heh1;
00381 }
00382 }
00383 }
00384
00385
00386
00387
00388
00389 template <class MeshT, class PointT>
00390 void
00391 MeshEdgeSamplerT<MeshT, PointT>::
00392 get_end_fhs_set( const Point& _p_end,
00393 const FH _fh_end,
00394 std::vector<FH>& _endfhs)
00395 {
00396 _endfhs.clear();
00397 _endfhs.push_back( _fh_end );
00398
00399 std::map<int, bool> stored_fh;
00400 stored_fh[ _fh_end.idx()] = true;
00401
00402 double eps = epsilon( _fh_end);
00403
00404 typename Mesh::ConstFaceVertexIter fv_it = mesh_.cfv_iter(_fh_end);
00405
00406 for(; fv_it; ++fv_it)
00407 {
00408 typename Mesh::ConstVertexFaceIter vf_iter = mesh_.cvf_iter(fv_it.handle());
00409 for(; vf_iter; ++vf_iter)
00410 {
00411 FH cur_fh = vf_iter.handle();
00412
00413
00414 if( stored_fh.find(cur_fh.idx()) != stored_fh.end())
00415 continue;
00416
00417
00418 HEH heh0 = mesh_.halfedge_handle( cur_fh);
00419 HEH heh1 = mesh_.next_halfedge_handle( heh0);
00420 HEH heh2 = mesh_.next_halfedge_handle( heh1);
00421
00422 Point p0 = (Point)mesh_.point( mesh_.to_vertex_handle( heh0));
00423 Point p1 = (Point)mesh_.point( mesh_.to_vertex_handle( heh1));
00424 Point p2 = (Point)mesh_.point( mesh_.to_vertex_handle( heh2));
00425
00426 Point pc;
00427 double d = ACG::Geometry::distPointTriangle( _p_end,
00428 p0,
00429 p1,
00430 p2,
00431 pc);
00432
00433 if( d < eps )
00434 {
00435 _endfhs.push_back( cur_fh);
00436
00437 stored_fh[cur_fh.idx()] = true;
00438 }
00439 }
00440 }
00441 }
00442
00443
00444
00445
00446
00447 template <class MeshT, class PointT>
00448 double
00449 MeshEdgeSamplerT<MeshT, PointT>::
00450 plane_line_intersection( const Point& _p0,
00451 const Point& _p1,
00452 Point& _p_int)
00453 {
00454 double a = (n_plane_ | (p_plane_-_p0));
00455 double b = (n_plane_ | (_p1-_p0));
00456
00457 if( fabs(b) > 1e-8)
00458 {
00459 double s = a/b;
00460
00461 _p_int = _p0 + (_p1-_p0)*s;
00462
00463
00464 if( fabs((n_plane_| (_p_int-p_plane_)) ) > 1e-8)
00465 std::cerr << "WARNING (MeshEdgeSamplerT): wrong intersection point!!!\n";
00466
00467
00468
00469 if( s >= 0.0 && s<= 1.0)
00470 return 0.0;
00471 else
00472 return std::min( (_p_int-_p1).norm(), (_p_int-_p0).norm());
00473 }
00474 else
00475 {
00476 std::cerr << "WARNING (MeshEdgeSamplerT): Line and Plane parallel!!!\n";
00477 return fabs((n_plane_| (_p0-p_plane_)));
00478 }
00479 }
00480
00481
00482
00483
00484 template <class MeshT, class PointT>
00485 double
00486 MeshEdgeSamplerT<MeshT, PointT>::
00487 plane_line_intersection( const HEH _heh,
00488 Point& _p_int)
00489 {
00490 Point p0 = mesh_.point(mesh_.from_vertex_handle(_heh));
00491 Point p1 = mesh_.point(mesh_. to_vertex_handle(_heh));
00492
00493 return plane_line_intersection( p0, p1, _p_int);
00494 }
00495
00496
00497
00498
00499
00500 template <class MeshT, class PointT>
00501 bool
00502 MeshEdgeSamplerT<MeshT, PointT>::
00503 line_in_plane( const Point& _p0,
00504 const Point& _p1,
00505 double _eps)
00506 {
00507 if( plane_dist( (_p0+_p1)*0.5) < _eps &&
00508 ((_p1-_p0).normalize() | n_plane_) < _eps )
00509 return true;
00510 else
00511 return false;
00512 }
00513
00514
00515
00516
00517
00518 template <class MeshT, class PointT>
00519 bool
00520 MeshEdgeSamplerT<MeshT, PointT>::
00521 line_in_plane( const HEH& _heh )
00522 {
00523 Point p0 = mesh_.point(mesh_.from_vertex_handle(_heh));
00524 Point p1 = mesh_.point(mesh_. to_vertex_handle(_heh));
00525
00526 double eps = (p1-p0).norm()*3e-5;
00527
00528 return line_in_plane( p0, p1, eps);
00529 }
00530
00531
00532
00533
00534
00535 template <class MeshT, class PointT>
00536 double
00537 MeshEdgeSamplerT<MeshT, PointT>::
00538 plane_dist( const Point& _p0 )
00539
00540 {
00541 return fabs((n_plane_| (_p0-p_plane_)));
00542 }
00543
00544
00545
00546
00547 template <class MeshT, class PointT>
00548 double
00549 MeshEdgeSamplerT<MeshT, PointT>::
00550 line_line_dist(const Point& _p_start,
00551 const Point& _p_end,
00552 const HEH& _heh,
00553 Point& _p_best)
00554 {
00555 Point phe0 = mesh_.point(mesh_.to_vertex_handle(_heh));
00556 Point phe1 = mesh_.point(mesh_.to_vertex_handle(mesh_.opposite_halfedge_handle(_heh)));
00557 Point pb0;
00558
00559 return ACG::Geometry::distLineLine(_p_start,
00560 _p_end,
00561 phe0,
00562 phe1,
00563 &pb0,
00564 &_p_best);
00565 }
00566
00567
00568
00569
00570 template <class MeshT, class PointT>
00571 typename MeshEdgeSamplerT<MeshT, PointT>::HEH
00572 MeshEdgeSamplerT<MeshT, PointT>::
00573 get_next_edge_intersection( const HEH& _heh, const Point& _pold, Point& _pint)
00574 {
00575 HEH opp_heh = mesh_.opposite_halfedge_handle( _heh);
00576
00577 if( mesh_.is_boundary( _heh ))
00578 {
00579 std::cerr << "ERROR (MeshEdgeSamplerT): next edge was boundary!!!\n";
00580 return _heh;
00581 }
00582
00583
00584 HEH cheh0 = mesh_.next_halfedge_handle( opp_heh);
00585 HEH cheh1 = mesh_.next_halfedge_handle( cheh0 );
00586
00587
00588 if( line_in_plane( cheh0))
00589 {
00590 plane_line_intersection( cheh1, _pint);
00591 return cheh1;
00592 }
00593 else if( line_in_plane( cheh1))
00594 {
00595 plane_line_intersection( cheh0, _pint);
00596 return cheh0;
00597 }
00598 else
00599 {
00600 Point p_int0, p_int1;
00601 double d0 = plane_line_intersection( cheh0, p_int0);
00602 double d1 = plane_line_intersection( cheh1, p_int1);
00603
00604 double eps = epsilon(_heh);
00605
00606
00607 if( d0 < eps && d1 < eps)
00608 {
00609
00610 if( (_pold-p_int0).norm() > (_pold-p_int1).norm())
00611 {
00612 _pint = p_int0;
00613 return cheh0;
00614 }
00615 else
00616 {
00617 _pint = p_int1;
00618 return cheh1;
00619 }
00620 }
00621 else
00622 {
00623 if( d0 <= d1 )
00624 {
00625 _pint = p_int0;
00626 return cheh0;
00627 }
00628 else
00629 {
00630 _pint = p_int1;
00631 return cheh1;
00632 }
00633 }
00634 }
00635 }
00636
00637
00638
00639
00640
00641 template <class MeshT, class PointT>
00642 void
00643 MeshEdgeSamplerT<MeshT, PointT>::
00644 sort_intersections( HEH& _heh0, double& _d0, Point& _ip0,
00645 HEH& _heh1, double& _d1, Point& _ip1,
00646 HEH& _heh2, double& _d2, Point& _ip2 )
00647 {
00648 if( _d0 > _d1)
00649 {
00650 std::swap( _heh0, _heh1);
00651 std::swap( _d0, _d1);
00652 std::swap( _ip0, _ip1);
00653 }
00654
00655 if( _d1 > _d2)
00656 {
00657 std::swap( _heh1, _heh2);
00658 std::swap( _d1, _d2);
00659 std::swap( _ip1, _ip2);
00660 }
00661
00662 if( _d0 > _d1)
00663 {
00664 std::swap( _heh0, _heh1);
00665 std::swap( _d0, _d1);
00666 std::swap( _ip0, _ip1);
00667 }
00668 }
00669
00670
00671
00672
00673
00674 template <class MeshT, class PointT>
00675 double
00676 MeshEdgeSamplerT<MeshT, PointT>::
00677 epsilon( const FH& _fh)
00678 {
00679
00680 HEH heh0 = mesh_.halfedge_handle( _fh);
00681 HEH heh1 = mesh_.next_halfedge_handle( heh0);
00682 HEH heh2 = mesh_.next_halfedge_handle( heh1);
00683
00684 Point p0 = (Point)mesh_.point( mesh_.to_vertex_handle( heh0));
00685 Point p1 = (Point)mesh_.point( mesh_.to_vertex_handle( heh1));
00686 Point p2 = (Point)mesh_.point( mesh_.to_vertex_handle( heh2));
00687
00688 return 1e-5*((p1-p0).norm() + (p2-p1).norm() + (p0-p2).norm());
00689 }
00690
00691
00692
00693
00694 template <class MeshT, class PointT>
00695 double
00696 MeshEdgeSamplerT<MeshT, PointT>::
00697 epsilon( const HEH& _heh)
00698 {
00699
00700 Point p0 = (Point)mesh_.point( mesh_.to_vertex_handle ( _heh));
00701 Point p1 = (Point)mesh_.point( mesh_.from_vertex_handle( _heh));
00702
00703 return 3e-5*((p1-p0).norm());
00704 }
00705
00706
00707
00708
00709
00710 template <class MeshT, class PointT>
00711 void
00712 MeshEdgeSamplerT<MeshT, PointT>::
00713 finish_list( std::vector<Point>& _points,
00714 std::vector<EH>& _ehs,
00715 const HEH _cur_heh,
00716 const FH _fh_end,
00717 const Point& _p_end,
00718 const int _type)
00719
00720 {
00721
00722 HEH cur_opp_heh = mesh_.opposite_halfedge_handle(_cur_heh);
00723 FH cur_fh = mesh_.face_handle( cur_opp_heh);
00724
00725
00726 HEH heh0 = mesh_.next_halfedge_handle( cur_opp_heh );
00727 HEH heh1 = mesh_.next_halfedge_handle( heh0);
00728
00729
00730 if( cur_fh == _fh_end) return;
00731 else if( _type == 2)
00732 {
00733 FH fhc0 = mesh_.face_handle(mesh_.opposite_halfedge_handle(heh0));
00734 FH fhc1 = mesh_.face_handle(mesh_.opposite_halfedge_handle(heh1));
00735 FH fhc2 = mesh_.face_handle(_cur_heh);
00736
00737
00738 _points.push_back(_p_end);
00739
00740 if( fhc0 == _fh_end)
00741 _ehs.push_back( mesh_.edge_handle(heh0));
00742 else
00743 if( fhc1 == _fh_end)
00744 _ehs.push_back( mesh_.edge_handle(heh1));
00745 else
00746 {
00747 _ehs.push_back(mesh_.edge_handle(heh0));
00748 std::cerr << "ERROR: could not find end fh...\n";
00749 std::cerr << (fhc2.idx() == _fh_end.idx()) << std::endl;
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767 }
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811 }
00812 else if( _type > 2)
00813 {
00814 std::vector<EH> cw_ehs;
00815 circulate_CW( heh1, _fh_end, cw_ehs);
00816
00817 std::vector<EH> ccw_ehs;
00818 circulate_CCW(heh0, _fh_end, ccw_ehs);
00819
00820
00821 if( cw_ehs.size() < ccw_ehs.size())
00822 {
00823 for(unsigned int i=0; i<cw_ehs.size(); ++i)
00824 {
00825 _ehs.push_back( cw_ehs[i]);
00826 _points.push_back( _p_end);
00827 }
00828 }
00829 else
00830 {
00831 for(unsigned int i=0; i<ccw_ehs.size(); ++i)
00832 {
00833 _ehs.push_back( ccw_ehs[i]);
00834 _points.push_back( _p_end);
00835 }
00836 }
00837
00838 if( cw_ehs.size() == 0 && ccw_ehs.size() == 0)
00839 {
00840 std::cerr << "circulation failed vidx: " << mesh_.to_vertex_handle( heh0).idx() << std::endl;
00841 mesh_.status( mesh_.to_vertex_handle( heh0)).set_selected(true);
00842 }
00843 }
00844 }
00845
00846
00847
00848
00849
00850 template <class MeshT, class PointT>
00851 void
00852 MeshEdgeSamplerT<MeshT, PointT>::
00853 finish_list_old( std::vector<Point>& _points,
00854 std::vector<EH>& _ehs,
00855 const HEH _cur_heh,
00856 const FH _fh_end,
00857 const Point& _p_end,
00858 const int _t)
00859 {
00860
00861 HEH cur_opp_heh = mesh_.opposite_halfedge_handle(_cur_heh);
00862 FH cur_fh = mesh_.face_handle( cur_opp_heh);
00863
00864
00865 HEH heh0 = mesh_.next_halfedge_handle( cur_opp_heh );
00866 HEH heh1 = mesh_.next_halfedge_handle( heh0);
00867
00868
00869 double eps = epsilon( cur_fh );
00870
00871 VH circulate_vh(-1);
00872
00873
00874 if( cur_fh == _fh_end) return;
00875 else
00876 {
00877
00878 Point p0 = mesh_.point( mesh_.to_vertex_handle(heh0));
00879 Point p1 = mesh_.point( mesh_.to_vertex_handle(heh1));
00880 Point p2 = mesh_.point( mesh_.to_vertex_handle(cur_opp_heh));
00881
00882 double d0 = (_p_end - p0).norm();
00883 double d1 = (_p_end - p1).norm();
00884 double d2 = (_p_end - p2).norm();
00885
00886 std::cerr << "d0 d1 d2 " << d0 << " " << d1 << " " << d2 << std::endl;
00887 std::cerr << mesh_.to_vertex_handle(heh0).idx() << " "
00888 << mesh_.to_vertex_handle(heh1).idx() << " "
00889 << mesh_.to_vertex_handle(cur_opp_heh).idx() << std::endl;
00890
00891
00892 if( d0 < eps) circulate_vh = mesh_.to_vertex_handle( heh0);
00893 else if( d1 < eps) circulate_vh = mesh_.to_vertex_handle( heh1);
00894 else if( d2 < eps) circulate_vh = mesh_.to_vertex_handle( cur_opp_heh);
00895 else
00896 {
00897
00898 double ed0 = ACG::Geometry::distPointLine( _p_end, p2, p0);
00899 double ed1 = ACG::Geometry::distPointLine( _p_end, p0, p1);
00900
00901
00902 _points.push_back(_p_end);
00903
00904 if( ed0 < eps)
00905 {
00906 _ehs.push_back( mesh_.edge_handle( heh0));
00907
00908 if( mesh_.face_handle( mesh_.opposite_halfedge_handle( heh0)) != _fh_end)
00909 std::cerr << "ERROR (MeshEdgeSamplerT): opposite edge handle is not correct (0) !!!\n";
00910 }
00911 else if( ed1 < eps)
00912 {
00913 _ehs.push_back( mesh_.edge_handle( heh1));
00914
00915 if( mesh_.face_handle( mesh_.opposite_halfedge_handle( heh1)) != _fh_end)
00916 std::cerr << "ERROR (MeshEdgeSamplerT): opposite edge handle is not correct (1) !!!\n";
00917 }
00918 else
00919 {
00920 std::cerr << "ERROR (MeshEdgeSamplerT): endpoint should be near edge...\n";
00921 _ehs.push_back( mesh_.edge_handle( heh0));
00922 }
00923 }
00924 }
00925
00926 if( circulate_vh == mesh_.to_vertex_handle(heh0))
00927 {
00928 std::vector<EH> cw_ehs;
00929 circulate_CW( heh1, _fh_end, cw_ehs);
00930
00931 std::vector<EH> ccw_ehs;
00932 circulate_CCW(heh0, _fh_end, ccw_ehs);
00933
00934
00935 if( cw_ehs.size() < ccw_ehs.size())
00936 {
00937 for(unsigned int i=0; i<cw_ehs.size(); ++i)
00938 {
00939 _ehs.push_back( cw_ehs[i]);
00940 _points.push_back( _p_end);
00941 }
00942 }
00943 else
00944 {
00945 for(unsigned int i=0; i<ccw_ehs.size(); ++i)
00946 {
00947 _ehs.push_back( ccw_ehs[i]);
00948 _points.push_back( _p_end);
00949 }
00950 }
00951 }
00952 else if( circulate_vh == mesh_.to_vertex_handle(heh1))
00953 {
00954 std::vector<EH> ccw_ehs;
00955 circulate_CCW(heh1, _fh_end, ccw_ehs);
00956
00957 for(unsigned int i=0; i<ccw_ehs.size(); ++i)
00958 {
00959 _ehs.push_back( ccw_ehs[i]);
00960 _points.push_back( _p_end);
00961 }
00962 }
00963 else if( circulate_vh == mesh_.to_vertex_handle(cur_opp_heh))
00964 {
00965 std::vector<EH> cw_ehs;
00966 circulate_CW(heh0, _fh_end, cw_ehs);
00967
00968 for(unsigned int i=0; i<cw_ehs.size(); ++i)
00969 {
00970 _ehs.push_back( cw_ehs[i]);
00971 _points.push_back( _p_end);
00972 }
00973 }
00974 }
00975
00976
00977
00978
00979
00980 template <class MeshT, class PointT>
00981 void
00982 MeshEdgeSamplerT<MeshT, PointT>::
00983 circulate_CW(HEH _heh, FH _fh_end, std::vector<EH>& _cw_ehs)
00984 {
00985 _cw_ehs.clear();
00986
00987
00988 HEH cur_heh = _heh;
00989 _cw_ehs.push_back( mesh_.edge_handle(cur_heh) );
00990
00991 while( mesh_.face_handle(mesh_.opposite_halfedge_handle( cur_heh)) != _fh_end )
00992 {
00993 cur_heh = mesh_.opposite_halfedge_handle( cur_heh);
00994 cur_heh = mesh_.next_halfedge_handle(cur_heh);
00995
00996 _cw_ehs.push_back( mesh_.edge_handle( cur_heh));
00997
00998
00999 if( cur_heh == _heh)
01000 {
01001 std::cerr << "ERROR (MeshEdgeSamplerT): circulate_CW could not find _fh_end... "
01002 << _cw_ehs.size() << std::endl;
01003 _cw_ehs.clear();
01004 break;
01005 }
01006 }
01007 }
01008
01009
01010
01011
01012
01013 template <class MeshT, class PointT>
01014 void
01015 MeshEdgeSamplerT<MeshT, PointT>::
01016 circulate_CCW(HEH _heh, FH _fh_end, std::vector<EH>& _ccw_ehs)
01017 {
01018 _ccw_ehs.clear();
01019
01020
01021 HEH cur_heh = _heh;
01022 _ccw_ehs.push_back( mesh_.edge_handle(cur_heh) );
01023
01024 while( mesh_.face_handle(mesh_.opposite_halfedge_handle( cur_heh)) != _fh_end )
01025 {
01026 cur_heh = mesh_.opposite_halfedge_handle( cur_heh);
01027 cur_heh = mesh_.next_halfedge_handle(cur_heh);
01028 cur_heh = mesh_.next_halfedge_handle(cur_heh);
01029
01030 _ccw_ehs.push_back( mesh_.edge_handle( cur_heh));
01031
01032
01033 if( cur_heh == _heh)
01034 {
01035 std::cerr << "ERROR (MeshEdgeSamplerT): circulate_CCW could not find _fh_end... "
01036 << _ccw_ehs.size() << std::endl;
01037 _ccw_ehs.clear();
01038 break;
01039 }
01040 }
01041 }
01042
01043
01044 }
01045