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
00051 #define ACG_POLYLINET_C
00052
00053
00054
00055 #include <OpenMesh/Core/Geometry/VectorT.hh>
00056
00057 #include <iostream>
00058 #include <fstream>
00059 #include <map>
00060
00061 #include "PolyLineT.hh"
00062 #include "MeshEdgeSamplerT.hh"
00063
00064 #include <float.h>
00065 #include <ACG/Geometry/Algorithms.hh>
00066
00067 #ifdef USE_PHYSIM
00068 #include <PhySim/Meshes/ConstrainedDelaunayT.hh>
00069 #endif
00070
00071 #ifndef WIN32
00072 #include <stdlib.h>
00073 #endif
00074
00075 #ifdef USE_OPENMP
00076 #include <omp.h>
00077 #endif
00078
00079
00080
00081 namespace ACG {
00082
00083
00084
00085
00086
00087 template <class MT>
00088 class Ecmp
00089 {
00090 public:
00091 Ecmp( MT& _mesh, typename MT::Point _v) : mesh_(_mesh), v_(_v) {}
00092
00093 bool operator()(const int& _vidx0, const int& _vidx1)
00094 {
00095 typename MT::Scalar d0 = (mesh_.point( mesh_.vertex_handle(_vidx0)) | v_);
00096 typename MT::Scalar d1 = (mesh_.point( mesh_.vertex_handle(_vidx1)) | v_);
00097
00098 return d0 < d1;
00099 }
00100
00101
00102 MT& mesh_;
00103 typename MT::Point v_;
00104 };
00105
00106
00107
00108
00109
00111 template <class PointT>
00112 PolyLineT<PointT>::
00113 PolyLineT( bool _closed )
00114 : closed_(_closed),
00115 ref_count_vnormals_(0),
00116 ref_count_vcolors_(0),
00117 ref_count_vscalars_(0),
00118 ref_count_vselections_(0),
00119 ref_count_vvhandles_(0),
00120 ref_count_vehandles_(0),
00121 ref_count_vfhandles_(0),
00122 ref_count_enormals_(0),
00123 ref_count_ecolors_(0),
00124 ref_count_escalars_(0),
00125 ref_count_eselections_(0)
00126 {
00127 }
00128
00129
00130
00132 template <class PointT>
00133 PolyLineT<PointT>::
00134 PolyLineT( const PolyLineT& _line )
00135 {
00136 closed_ = _line.closed_;
00137
00138
00139 points_ = _line.points_;
00140
00141
00142 vnormals_ = _line.vnormals_;
00143 vcolors_ = _line.vcolors_;
00144 vscalars_ = _line.vscalars_;
00145 vselections_ = _line.vselections_;
00146 vvhandles_ = _line.vvhandles_;
00147 vehandles_ = _line.vehandles_;
00148 vfhandles_ = _line.vfhandles_;
00149
00150
00151 enormals_ = _line.enormals_;
00152 ecolors_ = _line.ecolors_;
00153 escalars_ = _line.escalars_;
00154 eselections_ = _line.eselections_;
00155
00156
00157 ref_count_vnormals_ = _line.ref_count_vnormals_;
00158 ref_count_vcolors_ = _line.ref_count_vcolors_;
00159 ref_count_vscalars_ = _line.ref_count_vscalars_;
00160 ref_count_vselections_ = _line.ref_count_vselections_;
00161 ref_count_vvhandles_ = _line.ref_count_vvhandles_;
00162 ref_count_vehandles_ = _line.ref_count_vehandles_;
00163 ref_count_vfhandles_ = _line.ref_count_vfhandles_;
00164
00165 ref_count_enormals_ = _line.ref_count_enormals_;
00166 ref_count_ecolors_ = _line.ref_count_ecolors_;
00167 ref_count_escalars_ = _line.ref_count_escalars_;
00168 ref_count_eselections_ = _line.ref_count_eselections_;
00169 }
00170
00171
00172
00173
00174 template <class PointT>
00175 void
00176 PolyLineT<PointT>::
00177 clear()
00178 {
00179 points_.clear();
00180
00181
00182 vnormals_.clear();
00183 vcolors_.clear();
00184 vscalars_.clear();
00185 vselections_.clear();
00186 vvhandles_.clear();
00187 vehandles_.clear();
00188 vfhandles_.clear();
00189
00190 enormals_.clear();
00191 ecolors_.clear();
00192 escalars_.clear();
00193 eselections_.clear();
00194 }
00195
00196
00197
00198
00199
00200 template <class PointT>
00201 void
00202 PolyLineT<PointT>::
00203 resize( unsigned int _n)
00204 {
00205 if( _n < n_vertices())
00206 {
00207
00208 points_.resize( _n);
00209
00210
00211 if( vertex_normals_available() )
00212 vnormals_.resize( _n);
00213 if( vertex_colors_available())
00214 vcolors_.resize( _n);
00215 if( vertex_scalars_available())
00216 vscalars_.resize( _n);
00217 if( vertex_selections_available())
00218 vselections_.resize( _n);
00219 if( vertex_vhandles_available())
00220 vvhandles_.resize( _n);
00221 if( vertex_ehandles_available())
00222 vehandles_.resize( _n);
00223 if( vertex_fhandles_available())
00224 vfhandles_.resize( _n);
00225
00226 if( edge_normals_available())
00227 enormals_.resize( _n);
00228 if( edge_colors_available())
00229 ecolors_.resize( _n);
00230 if( edge_scalars_available())
00231 escalars_.resize( _n);
00232 if( edge_selections_available())
00233 eselections_.resize( _n);
00234 }
00235 else
00236 {
00237 while( n_vertices() < _n)
00238 add_point( Point());
00239 }
00240 }
00241
00242
00243
00244
00245
00246 template <class PointT>
00247 void
00248 PolyLineT<PointT>::
00249 add_point(const Point& _p)
00250 {
00251
00252 points_.push_back( _p );
00253
00254
00255 if( vertex_normals_available() )
00256 vnormals_.push_back( Point(0,0,0));
00257
00258 if( vertex_colors_available())
00259 vcolors_.push_back( Point(1,0,1));
00260
00261 if( vertex_scalars_available())
00262 vscalars_.push_back( 0.0 );
00263
00264 if( vertex_selections_available())
00265 vselections_.push_back( false);
00266
00267 if( vertex_vhandles_available())
00268 vvhandles_.push_back(-1);
00269
00270 if( vertex_ehandles_available())
00271 vehandles_.push_back(-1);
00272
00273 if( vertex_fhandles_available())
00274 vfhandles_.push_back(-1);
00275
00276 if( edge_normals_available())
00277 enormals_.push_back( Point(0,0,0));
00278
00279 if( edge_colors_available())
00280 ecolors_.push_back( Point(1,0,1));
00281
00282 if( edge_scalars_available())
00283 escalars_.push_back( 0.0);
00284
00285 if( edge_selections_available())
00286 eselections_.push_back(false);
00287 }
00288
00289
00290
00291 template <class PointT>
00292 void
00293 PolyLineT<PointT>::
00294 insert_point(int _idx, const Point& _p)
00295 {
00296 assert(_idx < (int)n_vertices() );
00297
00298
00299 points_.insert(points_.begin()+_idx, _p);
00300
00301
00302 if( vertex_normals_available() )
00303 vnormals_.insert(vnormals_.begin()+_idx, Point(0,0,0));
00304
00305 if( vertex_colors_available())
00306 vcolors_.insert(vcolors_.begin()+_idx, Point(1,0,1));
00307
00308 if( vertex_scalars_available())
00309 vscalars_.insert(vscalars_.begin()+_idx, 0.0 );
00310
00311 if( vertex_selections_available())
00312 vselections_.insert(vselections_.begin()+_idx, false);
00313
00314 if( vertex_vhandles_available())
00315 vvhandles_.insert(vvhandles_.begin()+_idx, -1);
00316
00317 if( vertex_ehandles_available())
00318 vehandles_.insert(vehandles_.begin()+_idx, -1);
00319
00320 if( vertex_fhandles_available())
00321 vfhandles_.insert(vfhandles_.begin()+_idx, -1);
00322
00323 if( edge_normals_available())
00324 enormals_.insert(enormals_.begin()+_idx, Point(0,0,0));
00325
00326 if( edge_colors_available())
00327 ecolors_.insert(ecolors_.begin()+_idx, Point(1,0,1));
00328
00329 if( edge_scalars_available())
00330 escalars_.insert(escalars_.begin()+_idx, 0.0);
00331
00332 if( edge_selections_available())
00333 eselections_.insert(eselections_.begin()+_idx, false);
00334 }
00335
00336
00337
00338
00339
00340 template <class PointT>
00341 void
00342 PolyLineT<PointT>::
00343 delete_point(int _idx)
00344 {
00345 assert(_idx < (int)n_vertices() );
00346
00347
00348 points_.erase(points_.begin()+_idx);
00349
00350
00351
00352 if( vertex_normals_available() )
00353 vnormals_.erase(vnormals_.begin()+_idx);
00354
00355 if( vertex_colors_available())
00356 vcolors_.erase(vcolors_.begin()+_idx);
00357
00358 if( vertex_scalars_available())
00359 vscalars_.erase(vscalars_.begin()+_idx);
00360
00361 if( vertex_selections_available())
00362 vselections_.erase(vselections_.begin()+_idx);
00363
00364 if( vertex_vhandles_available())
00365 vvhandles_.erase(vvhandles_.begin()+_idx);
00366
00367 if( vertex_ehandles_available())
00368 vehandles_.erase(vehandles_.begin()+_idx);
00369
00370 if( vertex_fhandles_available())
00371 vfhandles_.erase(vfhandles_.begin()+_idx);
00372
00373 if( edge_normals_available())
00374 enormals_.erase(enormals_.begin()+_idx);
00375
00376 if( edge_colors_available())
00377 ecolors_.erase(ecolors_.begin()+_idx);
00378
00379 if( edge_scalars_available())
00380 escalars_.erase(escalars_.begin()+_idx);
00381
00382 if( edge_selections_available())
00383 eselections_.erase(eselections_.begin()+_idx);
00384 }
00385
00386
00387
00388
00389
00390 template <class PointT>
00391 typename PolyLineT<PointT>::Scalar
00392 PolyLineT<PointT>::
00393 length() const
00394 {
00395 Scalar l = 0;
00396
00397 unsigned int n = points_.size();
00398
00399 if( !closed_) --n;
00400
00401 for(unsigned int i=0; i<n; ++i)
00402 {
00403 l += (points_[(i+1)%n]-points_[i]).norm();
00404 }
00405
00406 return l;
00407 }
00408
00409
00410
00411
00412 template <class PointT>
00413 void
00414 PolyLineT<PointT>::
00415 subdivide_old(Scalar _largest)
00416 {
00417
00418 if(!points_.size()) return;
00419
00420 unsigned int n_subdivisions = 1;
00421
00422 while( n_subdivisions != 0)
00423 {
00424
00425 n_subdivisions = 0;
00426
00427 std::vector<Point> new_points;
00428
00429 new_points.push_back( points_[0]);
00430
00431
00432 Scalar l2 = _largest*_largest;
00433
00434 for(unsigned int i=1; i<points_.size(); ++i)
00435 {
00436 if( (new_points.back() - points_[i]).sqrnorm() > l2)
00437 {
00438 Point mid_point = (new_points.back() + points_[i])*0.5;
00439
00440 new_points.push_back( mid_point );
00441 ++n_subdivisions;
00442 }
00443
00444 new_points.push_back( points_[i]);
00445 }
00446
00447
00448 if( closed_)
00449 {
00450 if( (new_points.back() - points_[0]).sqrnorm() > l2)
00451 {
00452 Point mid_point = (new_points.back() + points_[0])*0.5;
00453 new_points.push_back( mid_point );
00454 ++n_subdivisions;
00455 }
00456 }
00457
00458
00459 resize( new_points.size() );
00460 points_ = new_points;
00461 }
00462 }
00463
00464
00465
00466
00467
00468 template <class PointT>
00469 void
00470 PolyLineT<PointT>::
00471 subdivide(Scalar _largest)
00472 {
00473
00474 if(!n_vertices()) return;
00475
00476 unsigned int n_subdivisions = 1;
00477
00478 while( n_subdivisions != 0)
00479 {
00480
00481 n_subdivisions = 0;
00482
00483
00484 PolyLineT<PointT> new_pl = *this;
00485 new_pl.resize(1);
00486 new_pl.copy_vertex_complete(*this, 0, 0);
00487
00488
00489 Scalar l2 = _largest*_largest;
00490
00491 for(unsigned int i=1; i<points_.size(); ++i)
00492 {
00493 if( (new_pl.point(new_pl.n_vertices()-1) - points_[i]).sqrnorm() > l2)
00494 {
00495 Point mid_point = (new_pl.point(new_pl.n_vertices()-1) + points_[i])*0.5;
00496
00497 new_pl.add_point( mid_point );
00498 ++n_subdivisions;
00499 }
00500
00501
00502 new_pl.resize( new_pl.n_vertices()+1);
00503 new_pl.copy_vertex_complete( *this, i, new_pl.n_vertices()-1);
00504 }
00505
00506
00507 if( closed_)
00508 {
00509 if( (new_pl.point(new_pl.n_vertices()-1) - points_[0]).sqrnorm() > l2)
00510 {
00511 Point mid_point = (new_pl.point(new_pl.n_vertices()-1) + points_[0])*0.5;
00512 new_pl.add_point( mid_point );
00513 ++n_subdivisions;
00514 }
00515 }
00516
00517
00518 *this = new_pl;
00519 }
00520 }
00521
00522
00523
00524
00525 template <class PointT>
00526 void
00527 PolyLineT<PointT>::
00528 collapse(Scalar _smallest)
00529 {
00530
00531 if(!n_vertices()) return;
00532
00533 unsigned int n_collapses = 1;
00534
00535 unsigned int n_iter = 0;
00536
00537 while( n_collapses != 0 && n_iter < 5)
00538 {
00539 ++n_iter;
00540 n_collapses = 0;
00541
00542
00543 PolyLineT<PointT> new_pl = *this;
00544 new_pl.resize(1);
00545 new_pl.copy_vertex_complete( *this, 0, 0);
00546
00547
00548 Scalar l2 = _smallest*_smallest;
00549
00550 for(unsigned int i=1; i<points_.size(); ++i)
00551 {
00552
00553 bool vertex_selected = false;
00554 if( vertex_selections_available() && vertex_selection(i))
00555 vertex_selected = true;
00556
00557 if( (new_pl.point(new_pl.n_vertices()-1) - points_[i]).sqrnorm() >= l2 ||
00558 vertex_selected ||
00559 (!closed_ && i==points_.size()-1) )
00560 {
00561
00562 new_pl.resize( new_pl.n_vertices()+1);
00563 new_pl.copy_vertex_complete( *this, i, new_pl.n_vertices()-1);
00564 }
00565 else ++n_collapses;
00566 }
00567
00568
00569 if( closed_)
00570 {
00571
00572 bool vertex_selected = false;
00573 if( vertex_selections_available() && vertex_selection(points_.size()-1))
00574 vertex_selected = true;
00575
00576 if( (new_pl.point(new_pl.n_vertices()-1) - points_[0]).sqrnorm() < l2 && !vertex_selected)
00577 {
00578 new_pl.resize( new_pl.n_vertices()-1);
00579 }
00580 else ++n_collapses;
00581 }
00582
00583
00584 *this = new_pl;
00585 }
00586 }
00587
00588
00589
00590
00591
00592 template <class PointT>
00593 void
00594 PolyLineT<PointT>::
00595 collapse_old(Scalar _smallest)
00596 {
00597
00598 if(!points_.size()) return;
00599
00600 unsigned int n_collapses = 1;
00601
00602 unsigned int n_iter = 0;
00603
00604 while( n_collapses != 0 && n_iter < 5)
00605 {
00606 ++n_iter;
00607 n_collapses = 0;
00608
00609 std::vector<Point> new_points;
00610
00611 new_points.push_back( points_[0]);
00612
00613
00614 Scalar l2 = _smallest*_smallest;
00615
00616 for(unsigned int i=1; i<points_.size(); ++i)
00617 {
00618 if( (new_points.back() - points_[i]).sqrnorm() >= l2)
00619 {
00620 new_points.push_back( points_[i]);
00621 }
00622 else ++n_collapses;
00623 }
00624
00625
00626 if( closed_)
00627 {
00628 if( (new_points.back() - points_[0]).sqrnorm() >= l2)
00629 {
00630 new_points.resize( new_points.size()-1);
00631 }
00632 else ++n_collapses;
00633 }
00634 else
00635 {
00636
00637 if( points_.back() != new_points.back())
00638 new_points.back() = points_.back();
00639 }
00640
00641
00642 resize( new_points.size() );
00643 points_ = new_points;
00644 }
00645 }
00646
00647
00648
00649
00650
00651 template <class PointT>
00652 void
00653 PolyLineT<PointT>::
00654 smooth_uniform_laplace()
00655 {
00656
00657 std::vector<Point> points_old( points_ );
00658
00659 int n = points_.size();
00660
00661 int is = 0;
00662 int ie = n;
00663
00664 if( !closed_ )
00665 {
00666 ++is;
00667 --ie;
00668 }
00669
00670 if( vertex_selections_available())
00671 {
00672 #ifdef USE_OPENMP
00673 #pragma omp parallel for
00674 #endif
00675 for( int i=is; i<ie; ++i)
00676 {
00677
00678 if( !vertex_selection(i))
00679
00680 points_[i] = (points_old[ (i-1+n)%n ] +
00681 points_old[ (i+n )%n ]*2.0 +
00682 points_old[ (i+1 )%n ] )*0.25;
00683
00684 }
00685 }
00686 else
00687 {
00688 #ifdef USE_OPENMP
00689 #pragma omp parallel for
00690 #endif
00691 for( int i=is; i<ie; ++i)
00692 {
00693
00694 points_[i] = (points_old[ (i-1+n)%n ] +
00695 points_old[ (i+n )%n ] * 2.0 +
00696 points_old[ (i+1 )%n ] )*0.25;
00697 }
00698 }
00699 }
00700
00701
00702
00703
00704
00705 template <class PointT>
00706 void
00707 PolyLineT<PointT>::
00708 smooth_uniform_laplace2()
00709 {
00710
00711 std::vector<Point> points_old( points_ );
00712
00713 int n = points_.size();
00714
00715 int is = 0;
00716 int ie = n;
00717
00718 if( !closed_ )
00719 {
00720 is+=2;
00721 ie-=2;
00722 }
00723
00724 if( vertex_selections_available())
00725 {
00726 #ifdef USE_OPENMP
00727 #pragma omp parallel for
00728 #endif
00729 for(int i=is; i<ie; ++i)
00730 {
00731
00732 if( !vertex_selection(i))
00733
00734 points_[i] -= (points_old[ (i-2+2*n)%n ] +
00735 points_old[ (i-1+2*n)%n ]*-4.0 +
00736 points_old[ (i )%n ]* 6.0 +
00737 points_old[ (i+1 )%n ]*-4.0 +
00738 points_old[ (i+2 )%n ] )/(16.0*2.0);
00739 }
00740 }
00741 else
00742 {
00743 #ifdef USE_OPENMP
00744 #pragma omp parallel for
00745 #endif
00746 for(int i=is; i<ie; ++i)
00747 {
00748
00749 points_[i] -= (points_old[ (i-2+2*n)%n ] +
00750 points_old[ (i-1+2*n)%n ]*-4.0 +
00751 points_old[ (i )%n ]* 6.0 +
00752 points_old[ (i+1 )%n ]*-4.0 +
00753 points_old[ (i+2 )%n ] )/(16.0*2.0);
00754 }
00755 }
00756 }
00757
00758
00759
00760
00761
00762 template <class PointT>
00763 void
00764 PolyLineT<PointT>::
00765 smooth_uniform_laplace3()
00766 {
00767
00768 std::vector<Point> points_old( points_ );
00769
00770 int n = points_.size();
00771
00772 int is = 0;
00773 int ie = n;
00774
00775 if( !closed_ )
00776 {
00777 is+=3;
00778 ie-=3;
00779 }
00780
00781 if( vertex_selections_available())
00782 {
00783 #ifdef USE_OPENMP
00784 #pragma omp parallel for
00785 #endif
00786 for( int i=is; i<ie; ++i)
00787 {
00788
00789 if( !vertex_selection(i))
00790
00791 points_[i] = (points_old[ (i-3+3*n)%n ] +
00792 points_old[ (i-2+3*n)%n ]*(-6.0) +
00793 points_old[ (i-1+3*n)%n ]*15.0 +
00794 points_old[ (i ) ]*(44.0) +
00795 points_old[ (i+1 )%n ]*15.0 +
00796 points_old[ (i+2 )%n ]*(-6.0) +
00797 points_old[ (i+3 )%n ] )/64.0;
00798
00799 }
00800 }
00801 else
00802 {
00803 #ifdef USE_OPENMP
00804 #pragma omp parallel for
00805 #endif
00806 for( int i=is; i<ie; ++i)
00807 {
00808
00809 points_[i] = (points_old[ (i-3+3*n)%n ] +
00810 points_old[ (i-2+3*n)%n ]*(-6.0) +
00811 points_old[ (i-1+3*n)%n ]*15.0 +
00812 points_old[ (i ) ]*(44.0) +
00813 points_old[ (i+1 )%n ]*15.0 +
00814 points_old[ (i+2 )%n ]*(-6.0) +
00815 points_old[ (i+3 )%n ] )/64.0;
00816 }
00817 }
00818 }
00819
00820
00821
00822
00823
00824 template <class PointT>
00825 template <class MeshT, class SpatialSearchT>
00826 void
00827 PolyLineT<PointT>::
00828 project_to_mesh( const MeshT& _mesh, SpatialSearchT * _ssearch)
00829 {
00830 typename MeshT::FaceHandle fh;
00831
00832 #ifdef USE_OPENMP
00833 #pragma omp parallel for
00834 #endif
00835 for(unsigned int i=0; i<points_.size(); ++i)
00836 {
00837 points_[i] = find_nearest_point( _mesh, points_[i], fh, _ssearch);
00838 }
00839 }
00840
00841
00842
00843
00844
00845 template <class PointT>
00846 template <class MeshT, class SpatialSearchT>
00847 void
00848 PolyLineT<PointT>::
00849 project_to_mesh( const std::vector<MeshT*> _mesh,
00850 std::vector<SpatialSearchT*>* _ssearch)
00851 {
00852 typename MeshT::FaceHandle fh;
00853
00854 #ifdef USE_OPENMP
00855 #pragma omp parallel for
00856 #endif
00857 for(int i=0; i< (int)points_.size(); ++i)
00858 {
00859
00860 typename MeshT::Scalar d_best = -1;
00861
00862
00863 Point p_best(0,0,0);
00864
00865
00866 for(unsigned int j=0; j<_mesh.size(); ++j)
00867 {
00868 double d_new(-1);
00869
00870 Point p_new;
00871 if(_ssearch != 0)
00872 p_new = find_nearest_point( *(_mesh[j]), points_[i], fh, ((*_ssearch)[j]), &d_new);
00873 else
00874 p_new = find_nearest_point( *(_mesh[j]), points_[i], fh, (SpatialSearchT*)0, &d_new);
00875
00876
00877 if( d_new < d_best || d_best == -1)
00878 {
00879 p_best = p_new;
00880 d_best = d_new;
00881 }
00882 }
00883
00884 if( d_best != -1)
00885 points_[i] = p_best;
00886 }
00887 }
00888
00889
00890
00891
00892
00893 template <class PointT>
00894 template <class MeshT, class SpatialSearchT>
00895 typename PolyLineT<PointT>::Point
00896 PolyLineT<PointT>::
00897 find_nearest_point( const MeshT& _mesh,
00898 const Point& _point,
00899 typename MeshT::FaceHandle& _fh,
00900 SpatialSearchT * _ssearch,
00901 double* _dbest)
00902 {
00903 typename MeshT::Point p0 = (typename MeshT::Point) _point;
00904
00905 typename MeshT::Point p_best = _mesh.point(_mesh.vertex_handle(0));
00906 typename MeshT::Scalar d_best = (p0-p_best).sqrnorm();
00907
00908 typename MeshT::FaceHandle fh_best;
00909
00910 if( _ssearch == 0 )
00911 {
00912
00913 typename MeshT::ConstFaceIter cf_it = _mesh.faces_begin();
00914 typename MeshT::ConstFaceIter cf_end = _mesh.faces_end();
00915
00916 for(; cf_it != cf_end; ++cf_it)
00917 {
00918 typename MeshT::ConstFaceVertexIter cfv_it = _mesh.cfv_iter(cf_it);
00919
00920 const typename MeshT::Point& pt0 = _mesh.point( cfv_it);
00921 const typename MeshT::Point& pt1 = _mesh.point( ++cfv_it);
00922 const typename MeshT::Point& pt2 = _mesh.point( ++cfv_it);
00923
00924 typename MeshT::Point ptn;
00925
00926 typename MeshT::Scalar d = Geometry::distPointTriangleSquared( p0,
00927 pt0,
00928 pt1,
00929 pt2,
00930 ptn );
00931
00932 if( d < d_best)
00933 {
00934 d_best = d;
00935 p_best = ptn;
00936
00937 fh_best = cf_it.handle();
00938 }
00939 }
00940
00941
00942 _fh = fh_best;
00943
00944
00945 if(_dbest)
00946 *_dbest = sqrt(d_best);
00947
00948
00949 return (Point) p_best;
00950 }
00951 else
00952 {
00953 typename MeshT::FaceHandle fh = _ssearch->nearest(p0).handle;
00954 typename MeshT::CFVIter fv_it = _mesh.cfv_iter(fh);
00955
00956 const typename MeshT::Point& pt0 = _mesh.point( fv_it);
00957 const typename MeshT::Point& pt1 = _mesh.point(++fv_it);
00958 const typename MeshT::Point& pt2 = _mesh.point(++fv_it);
00959
00960
00961 d_best = Geometry::distPointTriangleSquared(p0, pt0, pt1, pt2, p_best);
00962
00963
00964 _fh = fh;
00965
00966
00967 if(_dbest)
00968 *_dbest = sqrt(d_best);
00969
00970 return (Point) p_best;
00971 }
00972 }
00973
00974
00975
00976
00977 template <class PointT>
00978 template <class MeshT, class SpatialSearchT>
00979 void
00980 PolyLineT<PointT>::
00981 resample_on_mesh_edges( MeshT& _mesh, SpatialSearchT * _ssearch)
00982 {
00983
00984 PolyLineT<PointT> new_pl = *this;
00985
00986
00987 std::vector<Point> new_points;
00988 std::vector<typename MeshT::EdgeHandle> new_ehandles;
00989
00990
00991 Point p_start, p_end;
00992 typename MeshT::FaceHandle fh_start, fh_end;
00993
00994
00995 p_end = find_nearest_point( _mesh, point(0), fh_end, _ssearch);
00996
00997
00998 new_pl.resize(1);
00999 new_pl.copy_vertex_complete(*this, 0, 0);
01000 new_pl.point(0) = p_end;
01001
01002 if( new_pl.vertex_fhandles_available())
01003 new_pl.vertex_fhandle(0) = fh_end.idx();
01004 if( new_pl.vertex_ehandles_available())
01005 new_pl.vertex_ehandle(0) = -1;
01006
01007 MeshEdgeSamplerT<MeshT, Point> mesampler( _mesh );
01008
01009 for(unsigned int i=1; i<n_vertices(); ++i)
01010 {
01011
01012 p_start = p_end;
01013 fh_start = fh_end;
01014
01015 p_end = find_nearest_point( _mesh, point(i), fh_end , _ssearch);
01016
01017
01018 mesampler.edge_points_in_segment( p_start,
01019 p_end,
01020 fh_start,
01021 fh_end,
01022 new_points,
01023 new_ehandles );
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035 for( unsigned int j=0; j< new_points.size(); ++j)
01036 {
01037 new_pl.add_point( new_points[j]);
01038
01039 if( new_pl.vertex_ehandles_available())
01040 new_pl.vertex_ehandle( new_pl.n_vertices()-1) = new_ehandles[j].idx();
01041 if( new_pl.vertex_fhandles_available())
01042 new_pl.vertex_fhandle( new_pl.n_vertices()-1) = -1;
01043 }
01044
01045
01046 new_pl.resize( new_pl.n_vertices() + 1);
01047 new_pl.copy_vertex_complete(*this, i, new_pl.n_vertices()-1);
01048 new_pl.point(new_pl.n_vertices()-1) = p_end;
01049
01050 if( new_pl.vertex_fhandles_available())
01051 new_pl.vertex_fhandle( new_pl.n_vertices()-1) = fh_end.idx();
01052 if( new_pl.vertex_ehandles_available())
01053 new_pl.vertex_ehandle( new_pl.n_vertices()-1) = -1;
01054 }
01055
01056
01057 if(is_closed())
01058 {
01059
01060 p_start = p_end;
01061 fh_start = fh_end;
01062
01063 p_end = find_nearest_point( _mesh, point(0), fh_end , _ssearch);
01064
01065
01066 mesampler.edge_points_in_segment( p_start,
01067 p_end,
01068 fh_start,
01069 fh_end,
01070 new_points,
01071 new_ehandles );
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083 for( unsigned int j=0; j< new_points.size(); ++j)
01084 {
01085 new_pl.add_point( new_points[j]);
01086
01087 if( new_pl.vertex_ehandles_available())
01088 new_pl.vertex_ehandle( new_pl.n_vertices()-1) = new_ehandles[j].idx();
01089 if( new_pl.vertex_fhandles_available())
01090 new_pl.vertex_fhandle( new_pl.n_vertices()-1) = -1;
01091 }
01092 }
01093
01094
01095 *this = new_pl;
01096 }
01097
01098
01099
01100
01101 #ifdef USE_PHYSIM
01102
01103 template <class PointT>
01104 template <class MeshT, class SpatialSearchT>
01105 void
01106 PolyLineT<PointT>::
01107 integrate_into_mesh( MeshT& _mesh, SpatialSearchT * _ssearch)
01108 {
01109 if( is_closed() && points_.size() < 2)
01110 {
01111 std::cerr << "Warning: closed polyline with only one vertex!!!\n";
01112 return;
01113 }
01114
01115
01116 resample_on_mesh_edges( _mesh, _ssearch);
01117
01118
01119
01120 if( !vertex_ehandles_available() ||
01121 !vertex_fhandles_available() )
01122 {
01123 std::cerr << "ERROR: PolyLine::integrate_into_mesh needs ehandles and fhandles!!!\n";
01124 return;
01125 }
01126
01127
01128 add_boundary_points(_mesh);
01129
01130
01131 typedef std::pair<int,int> FSegment;
01132 typedef std::pair< std::vector< FSegment >, std::vector<int> > FData;
01133 typedef std::map< int, FData > FSPMap;
01134
01135
01136 FSPMap face_map;
01137
01138 typedef std::vector<int> EData;
01139 typedef std::map< int, EData > EVMap;
01140
01141
01142 EVMap edge_map;
01143
01144
01145 std::vector<int> plvhs;
01146 int last_eidx = -1;
01147 int last_fidx = -1;
01148 int last_vidx = -1;
01149 int boundary_closed = is_closed();
01150
01151 for(unsigned int i=0; i<points_.size()+boundary_closed; ++i)
01152 {
01153 int vidx = 0;
01154 int eidx = vertex_ehandle(i%points_.size());
01155 int fidx = vertex_fhandle(i%points_.size());
01156
01157
01158 if( i < points_.size())
01159 {
01160 plvhs.push_back( _mesh.add_vertex( (typename MeshT::Point) points_[i]).idx());
01161
01162 vidx = plvhs.back();
01163
01164
01165 if( eidx != -1 && fidx != -1)
01166 std::cerr << "ERROR: eidx and fidx are valid simultaneously, this shouldn't happen!!!!\n";
01167
01168
01169 if( eidx != -1)
01170 edge_map[eidx].push_back(vidx);
01171
01172
01173 if( fidx != -1)
01174 face_map[fidx].second.push_back( vidx );
01175 }
01176 else vidx = plvhs[0];
01177
01178
01179 if( i>0 )
01180 {
01181
01182 if( ( fidx != -1 && last_eidx != -1) ||
01183 ( eidx != -1 && last_fidx != -1) ||
01184 ( fidx != -1 && last_fidx != -1 && fidx == last_fidx) )
01185 {
01186 int valid_fidx = std::max(fidx, last_fidx);
01187
01188 face_map[valid_fidx].first.push_back( FSegment(vidx, last_vidx) );
01189 }
01190 else
01191 if( eidx != -1 && last_eidx != -1)
01192 {
01193 typename MeshT::EdgeHandle eh = _mesh.edge_handle( eidx );
01194 typename MeshT::HalfedgeHandle heh0= _mesh.halfedge_handle( eh, 0);
01195 typename MeshT::HalfedgeHandle heh1= _mesh.halfedge_handle( eh, 1);
01196
01197 typename MeshT::FaceHandle fh0, fh1;
01198
01199 if( !_mesh.is_boundary( heh0)) fh0 = _mesh.face_handle(heh0);
01200 else fh0 = _mesh.face_handle(heh1);
01201 if( !_mesh.is_boundary( heh1)) fh1 = _mesh.face_handle(heh1);
01202 else fh1 = _mesh.face_handle(heh0);
01203
01204 std::pair<int,int> fhs( fh0.idx(), fh1.idx());
01205
01206 typename MeshT::EdgeHandle last_eh = _mesh.edge_handle( last_eidx );
01207 typename MeshT::HalfedgeHandle last_heh0= _mesh.halfedge_handle( last_eh, 0);
01208 typename MeshT::HalfedgeHandle last_heh1= _mesh.halfedge_handle( last_eh, 1);
01209
01210 typename MeshT::FaceHandle last_fh0, last_fh1;
01211
01212 if( !_mesh.is_boundary( last_heh0)) last_fh0 = _mesh.face_handle(last_heh0);
01213 else last_fh0 = _mesh.face_handle(last_heh1);
01214 if( !_mesh.is_boundary( last_heh1)) last_fh1 = _mesh.face_handle(last_heh1);
01215 else last_fh1 = _mesh.face_handle(last_heh0);
01216
01217 std::pair<int,int> last_fhs( last_fh0.idx(), last_fh1.idx());
01218
01219 int common_fh = -1;
01220
01221 if( fhs.first == last_fhs.first ||
01222 fhs.first == last_fhs.second )
01223 common_fh = fhs.first;
01224 else
01225 if( fhs.second == last_fhs.first ||
01226 fhs.second == last_fhs.second )
01227 common_fh = fhs.second;
01228 else
01229 {
01230 std::cerr << "ERROR: Polyline::integrate_into_mesh no common facehandle!!!\n";
01231 }
01232
01233 face_map[common_fh].first.push_back( FSegment(vidx, last_vidx));
01234 }
01235 else
01236 {
01237 std::cerr << "ERROR: unhandled segment case!!!\n";
01238 std::cerr << "vidx: " << vidx << " / last " << last_vidx << std::endl;
01239 std::cerr << "fidx: " << fidx << " / last " << last_fidx << std::endl;
01240 std::cerr << "eidx: " << eidx << " / last " << last_eidx << std::endl;
01241
01242 }
01243 }
01244
01245
01246 last_eidx = eidx;
01247 last_fidx = fidx;
01248 last_vidx = vidx;
01249 }
01250
01251
01252 EVMap::iterator ev_it = edge_map.begin();
01253 for(; ev_it != edge_map.end(); ++ev_it)
01254 {
01255 typename MeshT::EdgeHandle eh = _mesh.edge_handle( ev_it->first );
01256 typename MeshT::Point p0 = _mesh.point( _mesh.to_vertex_handle( _mesh.halfedge_handle(eh,0)));
01257 typename MeshT::Point p1 = _mesh.point( _mesh.to_vertex_handle( _mesh.halfedge_handle(eh,1)));
01258
01259 std::sort( ev_it->second.begin(), ev_it->second.end(), Ecmp<MeshT>(_mesh, p0-p1 ));
01260 }
01261
01262
01263 FSPMap::iterator fsp_it = face_map.begin();
01264 for(; fsp_it != face_map.end(); ++fsp_it)
01265 {
01266 typename MeshT::FaceHandle fh = _mesh.face_handle( fsp_it->first );
01267 typename MeshT::FHIter fh_it = _mesh.fh_iter(fh);
01268 for(; fh_it; ++fh_it)
01269 {
01270
01271 typename MeshT::VertexHandle vh_start = _mesh.from_vertex_handle(fh_it.handle());
01272 typename MeshT::VertexHandle vh_end = _mesh.to_vertex_handle (fh_it.handle());
01273
01274 typename MeshT::EdgeHandle eh = _mesh.edge_handle( fh_it.handle());
01275
01276
01277 fsp_it->second.second.push_back( vh_start.idx() );
01278
01279
01280 std::vector<int> edge_ordered ( edge_map[ eh.idx()]);
01281 if( fh_it.handle() != _mesh.halfedge_handle(eh, 0) )
01282 std::reverse(edge_ordered.begin(), edge_ordered.end());
01283
01284 int prev_idx = vh_start.idx();
01285
01286 std::vector<int>::iterator ev_it = edge_ordered.begin();
01287 std::vector<int>::iterator ev_end = edge_ordered.end();
01288
01289 for(; ev_it != ev_end; ++ev_it)
01290 {
01291
01292 fsp_it->second.first.push_back( FSegment(prev_idx, *ev_it) );
01293
01294
01295 fsp_it->second.second.push_back( *ev_it );
01296
01297 prev_idx = *ev_it;
01298 }
01299
01300 fsp_it->second.first.push_back( FSegment(prev_idx, vh_end.idx()) );
01301 }
01302 }
01303
01304
01305 ev_it = edge_map.begin();
01306 for(; ev_it != edge_map.end(); ++ev_it)
01307 {
01308 typename MeshT::EdgeHandle eh = _mesh.edge_handle( ev_it->first );
01309 typename MeshT::HalfedgeHandle heh0 = _mesh.halfedge_handle( eh, 0 );
01310 typename MeshT::HalfedgeHandle heh1 = _mesh.halfedge_handle( eh, 1 );
01311
01312 edge_map[eh.idx()].push_back( _mesh.to_vertex_handle(heh0).idx());
01313 edge_map[eh.idx()].push_back( _mesh.to_vertex_handle(heh1).idx());
01314 }
01315
01316
01317
01318 ACG::ConstrainedDelaunayT<double> cdelaunay;
01319 std::vector<int> orig_idx;
01320 std::map<int,int> new_idx;
01321 fsp_it = face_map.begin();
01322 for(; fsp_it != face_map.end(); ++fsp_it)
01323 {
01324 typename MeshT::FaceHandle fh = _mesh.face_handle( fsp_it->first );
01325 int fidx = fh.idx();
01326
01327
01328 std::vector<int> ehs;
01329 typename MeshT::FEIter fe_it = _mesh.fe_iter( fh );
01330 for(; fe_it; ++fe_it)
01331 ehs.push_back( fe_it.handle().idx());
01332
01333
01334 cdelaunay.clear();
01335 cdelaunay.set_normal( _mesh.normal(fh) );
01336
01337
01338 orig_idx.clear();
01339 new_idx.clear();
01340 std::vector<int>::iterator fv_it = fsp_it->second.second.begin();
01341 std::vector<int>::iterator fv_end = fsp_it->second.second.end();
01342 for(; fv_it != fv_end; ++fv_it)
01343 {
01344 new_idx[*fv_it] = orig_idx.size();
01345 orig_idx.push_back( *fv_it );
01346 bool valid = cdelaunay.add_point((ACG::ConstrainedDelaunayT<double>::Vec3r) _mesh.point(_mesh.vertex_handle(*fv_it)));
01347
01348 if( !valid )
01349 {
01350 std::cerr << "ERROR: CGAL could not add point, aborting polyline integration...\n";
01351
01352 typename MeshT::VertexIter v_it = _mesh.vertices_begin();
01353 for(; v_it != _mesh.vertices_end(); ++v_it)
01354 {
01355 if( !_mesh.valence(v_it.handle()))
01356 _mesh.delete_vertex(v_it.handle());
01357 }
01358 _mesh.garbage_collection();
01359 _mesh.update_normals();
01360
01361 return;
01362 }
01363 }
01364
01365
01366 std::vector<FSegment>::iterator fc_it = fsp_it->second.first.begin();
01367 std::vector<FSegment>::iterator fc_end = fsp_it->second.first.end();
01368 for(; fc_it != fc_end; ++fc_it)
01369 {
01370 cdelaunay.add_constraint( new_idx[fc_it->first], new_idx[fc_it->second] );
01371 }
01372
01373
01374 std::vector< std::vector< int> > tri_list;
01375 cdelaunay.get_triangles( tri_list);
01376
01377
01378 _mesh.delete_face(fh, false);
01379
01380
01381 for(unsigned int i=0; i<tri_list.size(); ++i)
01382 {
01383 std::vector<typename MeshT::VertexHandle > tvhs;
01384 for(unsigned int j=0; j<tri_list[i].size(); ++j)
01385 tvhs.push_back( _mesh.vertex_handle( orig_idx[tri_list[i][j]]) );
01386
01387
01388 bool face_valid = true;
01389 for(unsigned int j=0; j<ehs.size(); ++j)
01390 {
01391 if( tvhs.size() == 3)
01392 {
01393
01394 std::vector<int>::iterator em_begin = edge_map[ehs[j]].begin();
01395 std::vector<int>::iterator em_end = edge_map[ehs[j]].end();
01396
01397
01398 if( std::find( em_begin, em_end, tvhs[0].idx()) != em_end &&
01399 std::find( em_begin, em_end, tvhs[1].idx()) != em_end &&
01400 std::find( em_begin, em_end, tvhs[2].idx()) != em_end )
01401 {
01402 face_valid = false;
01403 }
01404 }
01405 else std::cerr << "ERROR: integrate polyline found triangle which has not 3 vertices...\n";
01406 }
01407
01408
01409 if( face_valid)
01410 _mesh.add_face( tvhs );
01411
01412 }
01413 }
01414
01415
01416 for(unsigned int i=1; i<points_.size()+boundary_closed; ++i)
01417 {
01418
01419 typename MeshT::VertexHandle vh0 = _mesh.vertex_handle( plvhs[i-1] );
01420 typename MeshT::VertexHandle vh1 = _mesh.vertex_handle( plvhs[i%points_.size()] );
01421
01422
01423 bool found_edge = false;
01424 typename MeshT::VOHIter voh_it = _mesh.voh_iter(vh0);
01425 for(; voh_it; ++voh_it)
01426 if( _mesh.to_vertex_handle(voh_it.handle()) == vh1)
01427 {
01428 _mesh.status( _mesh.edge_handle( voh_it.handle())).set_selected(true);
01429 found_edge = true;
01430 }
01431
01432 if( !found_edge )
01433 std::cerr << "Warning: could not find polyline edge: "
01434 << i-1 << " to " << i%points_.size()
01435 << std::endl;
01436 }
01437
01438
01439 _mesh.garbage_collection();
01440 _mesh.update_normals();
01441 }
01442
01443 #endif
01444
01445
01446
01447
01448 template <class PointT>
01449 template <class MeshT>
01450 void
01451 PolyLineT<PointT>::
01452 add_boundary_points(MeshT& _mesh)
01453 {
01454
01455 if( ! vertex_fhandles_available() ) return;
01456
01457
01458 if( points_.empty()) return;
01459
01460 if( !is_closed() )
01461 {
01462
01463 int fidx = vertex_fhandle(0);
01464 if( fidx != -1)
01465 {
01466 typename MeshT::Point p = (typename MeshT::Point) (points_[0]);
01467
01468 double closest_dist = FLT_MAX;
01469 typename MeshT::Point closest_boundary(0,0,0), pb(0,0,0);
01470 int closest_eidx = -1;
01471 typename MeshT::FHIter fh_it = _mesh.fh_iter( _mesh.face_handle(fidx));
01472
01473 for(; fh_it; ++fh_it)
01474 {
01475 if( _mesh.is_boundary( _mesh.opposite_halfedge_handle(fh_it.handle())))
01476 {
01477 typename MeshT::Point v0 = _mesh.point(_mesh.to_vertex_handle (fh_it.handle()));
01478 typename MeshT::Point v1 = _mesh.point(_mesh.from_vertex_handle(fh_it.handle()));
01479
01480 double d = ACG::Geometry::distPointLineSquared(p, v0, v1, &pb);
01481
01482 if( d < closest_dist)
01483 {
01484 closest_dist = d;
01485 closest_boundary = pb;
01486 closest_eidx = _mesh.edge_handle( fh_it.handle()).idx();
01487 }
01488 }
01489 }
01490
01491
01492 if( closest_eidx != -1 )
01493 {
01494 insert_point( 0, closest_boundary);
01495 vertex_ehandle(0) = closest_eidx;
01496 }
01497
01498 }
01499
01500
01501 int pvidx = points_.size()-1;
01502 fidx = vertex_fhandle(pvidx);
01503 if( fidx != -1)
01504 {
01505 typename MeshT::Point p = (typename MeshT::Point) (points_[pvidx]);
01506
01507 double closest_dist = FLT_MAX;
01508 typename MeshT::Point closest_boundary(0,0,0), pb(0,0,0);
01509 int closest_eidx = -1;
01510 typename MeshT::FHIter fh_it = _mesh.fh_iter( _mesh.face_handle(fidx));
01511
01512 for(; fh_it; ++fh_it)
01513 {
01514 if( _mesh.is_boundary( _mesh.opposite_halfedge_handle(fh_it.handle())))
01515 {
01516 typename MeshT::Point v0 = _mesh.point(_mesh.to_vertex_handle (fh_it.handle()));
01517 typename MeshT::Point v1 = _mesh.point(_mesh.from_vertex_handle(fh_it.handle()));
01518
01519 double d = ACG::Geometry::distPointLineSquared(p, v0, v1, &pb);
01520
01521 if( d < closest_dist)
01522 {
01523 closest_dist = d;
01524 closest_boundary = pb;
01525 closest_eidx = _mesh.edge_handle( fh_it.handle()).idx();
01526 }
01527 }
01528 }
01529
01530
01531 if( closest_eidx != -1 )
01532 {
01533 add_point( closest_boundary);
01534 vertex_ehandle( points_.size()-1 ) = closest_eidx;
01535 }
01536 }
01537 }
01538 }
01539
01540
01541
01542
01543
01544 template <class PointT>
01545 template <class LineNodeT>
01546 LineNodeT*
01547 PolyLineT<PointT>::
01548 get_line_node(LineNodeT*& _line_node, int _mode)
01549 {
01550 typedef typename LineNodeT::value_type Vec3fL;
01551
01552 if( _mode == 0)
01553 {
01554
01555
01556
01557 _line_node = new LineNodeT(LineNodeT::LineSegmentsMode, 0, "PolyLine");
01558 _line_node->set_line_width(5.0);
01559
01560 _line_node->set_base_color(OpenMesh::Vec4f(0.2 + double(rand())/double(RAND_MAX)*0.8,
01561 0.2 + double(rand())/double(RAND_MAX)*0.8,
01562 0.2 + double(rand())/double(RAND_MAX)*0.8,
01563 1.0));
01564
01565 _line_node->show();
01566
01567
01568 for( unsigned int i=0; i<this->points().size()-1; ++i)
01569 {
01570 _line_node->add_line( (Vec3fL) this->points()[i ],
01571 (Vec3fL) this->points()[i+1] );
01572 }
01573
01574
01575 if(closed_)
01576 if( !this->points().empty() )
01577 {
01578 _line_node->add_point( (Vec3fL) this->points()[0]);
01579 }
01580
01581 return _line_node;
01582 }
01583 else
01584 {
01585
01586 _line_node = new LineNodeT(LineNodeT::PolygonMode, 0, "PolyLine");
01587 _line_node->set_line_width(5.0);
01588
01589 _line_node->set_base_color(OpenMesh::Vec4f(0.2 + double(rand())/double(RAND_MAX)*0.8,
01590 0.2 + double(rand())/double(RAND_MAX)*0.8,
01591 0.2 + double(rand())/double(RAND_MAX)*0.8,
01592 1.0));
01593
01594 _line_node->show();
01595
01596
01597 for( unsigned int i=0; i<this->points().size(); ++i)
01598 {
01599 _line_node->add_point( (Vec3fL) this->points()[i]);
01600 }
01601
01602
01603 if(closed_)
01604 if( !this->points().empty() )
01605 {
01606 _line_node->add_point( (Vec3fL) this->points()[0]);
01607 }
01608
01609 return _line_node;
01610 }
01611 }
01612
01613
01614
01615
01616
01617 template <class PointT>
01618 template <class LineNodeT>
01619 void
01620 PolyLineT<PointT>::
01621 set_line_node(LineNodeT*& _line_node, int _mode)
01622 {
01623
01624
01625
01626 clear();
01627
01628 if( _mode == 0)
01629 {
01630
01631
01632 const typename LineNodeT::PointVector& ln_points = _line_node->points();
01633
01634 for(unsigned int i=0; i<ln_points.size();)
01635 {
01636 if( i != ln_points.size()-1)
01637 add_point( (Point) ln_points[i] );
01638 else
01639 {
01640
01641 if( (ln_points[ln_points.size()-1]-ln_points[0]).sqrnorm() == 0)
01642 {
01643 closed_ = true;
01644 }
01645 else
01646 {
01647 closed_ = false;
01648 add_point( (Point) ln_points[i] );
01649 }
01650 }
01651
01652
01653
01654 if( i == 0) i+=1;
01655 else i+=2;
01656 }
01657 }
01658 else
01659 {
01660
01661 closed_ = true;
01662
01663 const typename LineNodeT::PointVector& ln_points( _line_node->points());
01664
01665 for(unsigned int i=0; i<ln_points.size(); ++i)
01666 {
01667 add_point( (Point) ln_points[i] );
01668 }
01669 }
01670 }
01671
01672
01673
01674
01675
01676 template <class PointT>
01677 void
01678 PolyLineT<PointT>::
01679 print() const
01680 {
01681 std::cerr << "****** PolyInfo ******\n";
01682 std::cerr << "closed : " << closed_ << std::endl;
01683 std::cerr << "#points: " << points_.size() << std::endl;
01684 for(unsigned int i=0; i<points_.size(); ++i)
01685 std::cerr << points_[i] << std::endl;
01686 }
01687
01688
01689
01690
01691
01692 template <class PointT>
01693 void
01694 PolyLineT<PointT>::
01695 load(const char* _filename)
01696 {
01697
01698 clear();
01699
01700 std::ifstream fin(_filename, std::ios::in);
01701
01702
01703 fin >> closed_;
01704
01705
01706 int num_points;
01707 fin >> num_points;
01708
01709
01710
01711
01712
01713 for(int i=0; i<num_points; ++i)
01714 {
01715 Scalar x,y,z;
01716 fin >> x;
01717 fin >> y;
01718 fin >> z;
01719 Point p(x,y,z);
01720 add_point(p);
01721 }
01722
01723
01724
01725
01726 std::string token;
01727
01728 fin >> token;
01729
01730 if(vertex_vhandles_available())
01731 {
01732 if( token == "VVHANDLES")
01733 {
01734
01735 for( unsigned int i=0; i<n_vertices(); ++i)
01736 fin >> vertex_vhandle(i);
01737
01738 fin >> token;
01739 }
01740 }
01741
01742 if(vertex_ehandles_available())
01743 {
01744 if( token == "VEHANDLES")
01745 {
01746
01747 for( unsigned int i=0; i<n_vertices(); ++i)
01748 {
01749 fin >> vertex_ehandle(i);
01750 }
01751
01752 fin >> token;
01753 }
01754 }
01755
01756 if(vertex_fhandles_available())
01757 {
01758 if( token == "VFHANDLES")
01759 {
01760
01761
01762 for( unsigned int i=0; i<n_vertices(); ++i)
01763 fin >> vertex_fhandle(i);
01764
01765 fin >> token;
01766 }
01767 }
01768
01769 fin.close();
01770 }
01771
01772
01773
01774
01775
01776 template <class PointT>
01777 void
01778 PolyLineT<PointT>::
01779 save(const char* _filename) const
01780 {
01781 std::ofstream fout(_filename, std::ios::out);
01782
01783
01784 fout << closed_ << std::endl;
01785
01786
01787 fout << points_.size() << std::endl;
01788
01789 std::cerr << "write " << _filename << std::endl;
01790 std::cerr << "#points: " << points_.size() << std::endl;
01791
01792
01793
01794 for(unsigned int i=0; i<points_.size(); ++i)
01795 {
01796
01797 fout << points_[i][0] << " ";
01798 fout << points_[i][1] << " ";
01799 fout << points_[i][2] << std::endl;
01800 }
01801
01802
01803
01804
01805 if(vertex_vhandles_available())
01806 {
01807 fout << "VVHANDLES" << std::endl;
01808 for( unsigned int i=0; i<n_vertices(); ++i)
01809 fout << vertex_vhandle(i) << std::endl;
01810 }
01811
01812 if(vertex_ehandles_available())
01813 {
01814 fout << "VEHANDLES" << std::endl;
01815 for( unsigned int i=0; i<n_vertices(); ++i)
01816 {
01817 fout << vertex_ehandle(i) << std::endl;
01818 }
01819 }
01820
01821 if(vertex_fhandles_available())
01822 {
01823 fout << "VFHANDLES" << std::endl;
01824 for( unsigned int i=0; i<n_vertices(); ++i)
01825 fout << vertex_fhandle(i) << std::endl;
01826 }
01827
01828 fout.close();
01829 }
01830
01831
01832
01833
01834
01835 template <class PointT>
01836 template <class PropT>
01837 void
01838 PolyLineT<PointT>::
01839 request_prop( unsigned int& _ref_count, PropT& _prop)
01840 {
01841 if(_ref_count == 0)
01842 {
01843 _ref_count = 1;
01844
01845 _prop.resize(n_vertices());
01846 }
01847 else ++_ref_count;
01848 }
01849
01850
01851
01852
01853
01854 template <class PointT>
01855 template <class PropT>
01856 void
01857 PolyLineT<PointT>::
01858 release_prop( unsigned int& _ref_count, PropT& _prop)
01859 {
01860 if( _ref_count <= 1)
01861 {
01862 _ref_count = 0;
01863 _prop.clear();
01864 }
01865 else --_ref_count;
01866 }
01867
01868
01869
01870
01871
01872 template <class PointT>
01873 void
01874 PolyLineT<PointT>::
01875 copy_vertex_complete(const PolyLineT<PointT>& _pl, unsigned int _i, unsigned int _j)
01876 {
01877
01878 if( n_vertices() <= _j || _pl.n_vertices() <= _i)
01879 {
01880 std::cerr << "Warning: invalid range in PolyLine::copy_vertex_complete ( "
01881 << _i << " " << _j << " ) " << std::endl;
01882 return;
01883 }
01884
01885
01886 point(_j) = _pl.point(_i);
01887
01888
01889
01890
01891 if( _pl.vertex_normals_available())
01892 if( vertex_normals_available())
01893 vertex_normal(_j) = _pl.vertex_normal(_i);
01894
01895
01896 if( _pl.vertex_colors_available())
01897 if( vertex_colors_available())
01898 vertex_color(_j) = _pl.vertex_color(_i);
01899
01900
01901 if( _pl.vertex_scalars_available())
01902 if( vertex_scalars_available())
01903 vertex_scalar(_j) = _pl.vertex_scalar(_i);
01904
01905
01906 if( _pl.vertex_selections_available())
01907 if( vertex_selections_available())
01908 vertex_selection(_j) = _pl.vertex_selection(_i);
01909
01910
01911 if( _pl.vertex_vhandles_available())
01912 if( vertex_vhandles_available())
01913 vertex_vhandle(_j) = _pl.vertex_vhandle(_i);
01914
01915
01916 if( _pl.vertex_ehandles_available())
01917 if( vertex_ehandles_available())
01918 vertex_ehandle(_j) = _pl.vertex_ehandle(_i);
01919
01920
01921 if( _pl.vertex_ehandles_available())
01922 if( vertex_ehandles_available())
01923 vertex_ehandle(_j) = _pl.vertex_ehandle(_i);
01924 }
01925
01926
01927
01928
01929
01930 template <class PointT>
01931 void
01932 PolyLineT<PointT>::
01933 copy_edge_complete(const PolyLineT<PointT>& _pl, unsigned int _i, unsigned int _j)
01934 {
01935
01936 if( n_edges() <= _j || _pl.n_edges() <= _i)
01937 {
01938 std::cerr << "Warning: invalid range in PolyLine::copy_edge_complete ( "
01939 << _i << " " << _j << " ) " << std::endl;
01940 return;
01941 }
01942
01943
01944 if( _pl.edge_selections_available())
01945 if( edge_selections_available())
01946 edge_selection(_j) = _pl.edge_selection(_i);
01947
01948
01949
01950 if( _pl.edge_normals_available())
01951 if( edge_normals_available())
01952 edge_normal(_j) = _pl.edge_normal(_i);
01953
01954
01955 if( _pl.edge_colors_available())
01956 if( edge_colors_available())
01957 edge_color(_j) = _pl.edge_color(_i);
01958
01959
01960 if( _pl.edge_scalars_available())
01961 if( edge_scalars_available())
01962 edge_scalar(_j) = _pl.edge_scalar(_i);
01963
01964
01965 if( _pl.edge_selections_available())
01966 if( edge_selections_available())
01967 edge_selection(_j) = _pl.edge_selection(_i);
01968
01969
01970 if( _pl.edge_selections_available())
01971 if( edge_selections_available())
01972 edge_selection(_j) = _pl.edge_selection(_i);
01973 }
01974
01975
01976
01977
01978
01979 template <class PointT>
01980 void
01981 PolyLineT<PointT>::
01982 invert()
01983 {
01984
01985 if(is_closed())
01986 {
01987 std::cerr << "Warning: inversion for closed polylines is not supported!!!\n";
01988 return;
01989 }
01990
01991 PolyLineT<PointT> pl_temp = *this;
01992
01993
01994 for(unsigned int i=0; i<n_vertices(); ++i)
01995 pl_temp.copy_vertex_complete( *this, n_vertices()-1-i, i);
01996
01997
01998 for(unsigned int i=0; i<n_edges(); ++i)
01999 pl_temp.copy_edge_complete( *this, n_edges()-1-i, i);
02000
02001
02002 *this = pl_temp;
02003 }
02004
02005
02006
02007
02008
02009 template <class PointT>
02010 void
02011 PolyLineT<PointT>::
02012 append(const PolyLineT<PointT>& _pl)
02013 {
02014
02015 if( is_closed() || _pl.is_closed())
02016 {
02017 std::cerr << is_closed() << " " << _pl.is_closed() << std::endl;
02018 std::cerr << "Warning: appending not supported for closed polylines!!!\n";
02019 return;
02020 }
02021
02022 unsigned int old_nv = n_vertices();
02023 unsigned int old_ne = n_edges();
02024
02025 resize( n_vertices() + _pl.n_vertices());
02026
02027 for( unsigned int i=0; i<_pl.n_vertices(); ++i)
02028 copy_vertex_complete( _pl, i, i+old_nv);
02029
02030 for( unsigned int i=0; i<_pl.n_edges(); ++i)
02031 copy_edge_complete( _pl, i, i+old_ne+1);
02032 }
02033
02034
02035
02036
02037
02038 template <class PointT>
02039 void
02040 PolyLineT<PointT>::
02041 prepend(const PolyLineT<PointT>& _pl)
02042 {
02043 PolyLineT<PointT> pl_temp = _pl;
02044
02045 pl_temp.append(*this);
02046 *this = pl_temp;
02047 }
02048
02049
02050
02051
02052
02053 template <class PointT>
02054 void
02055 PolyLineT<PointT>::
02056 split_closed( unsigned int _split_idx)
02057 {
02058 if(!is_closed())
02059 {
02060 std::cerr << "Warning: split_closed was called for open polyline!\n";
02061 return;
02062 }
02063
02064
02065 PolyLineT<PointT> pl_temp = *this;
02066 pl_temp.resize(n_vertices()+1);
02067 pl_temp.set_closed( false);
02068
02069
02070
02071 for(unsigned int i=0; i<n_vertices()+1; ++i)
02072 pl_temp.copy_vertex_complete( *this, (i+_split_idx)%n_vertices(),i);
02073
02074 for(unsigned int i=0; i<n_edges(); ++i)
02075 pl_temp.copy_edge_complete( *this, (i+_split_idx)%n_edges(),i);
02076
02077
02078 *this = pl_temp;
02079 }
02080
02081
02082
02083
02084
02085 template <class PointT>
02086 void
02087 PolyLineT<PointT>::
02088 split( unsigned int _split_idx, PolyLineT<PointT>& _new_pl)
02089 {
02090 if( is_closed() ) split_closed( _split_idx);
02091 else
02092 {
02093
02094 _new_pl = *this;
02095
02096 _new_pl.resize( n_vertices() - _split_idx);
02097
02098
02099 for(unsigned int i=_split_idx; i<n_vertices(); ++i)
02100 _new_pl.copy_vertex_complete(*this, i, i-_split_idx);
02101
02102 for(unsigned int i=_split_idx; i<n_edges(); ++i)
02103 _new_pl.copy_edge_complete(*this, i, i-_split_idx);
02104
02105
02106 resize(_split_idx+1);
02107 }
02108 }
02109
02110
02111
02112
02113
02114 template <class PointT>
02115 template <class IPoint>
02116 bool
02117 PolyLineT<PointT>::
02118 plane_line_intersection( const IPoint& _p_plane,
02119 const IPoint& _n_plane,
02120 const IPoint& _p0,
02121 const IPoint& _p1,
02122 IPoint& _p_int)
02123 {
02124 double a = (_n_plane | (_p_plane-_p0));
02125 double b = (_n_plane | (_p1-_p0));
02126
02127 if( fabs(b) > 1e-9)
02128 {
02129 double s = a/b;
02130
02131 if( s >= 0.0 && s<= 1.0)
02132 {
02133 _p_int = _p0 + (_p1-_p0)*s;
02134
02135
02136 if( fabs((_n_plane| (_p_int-_p_plane)) ) > 1e-9)
02137 std::cerr << "WARNING: wrong intersection point!!!\n";
02138
02139 return true;
02140 }
02141 else
02142 return false;
02143 }
02144 else return false;
02145 }
02146
02147
02148
02149
02150
02151 template <class PointT>
02152 template<class MeshT>
02153 void
02154 PolyLineT<PointT>::
02155 edge_points_in_segment( const MeshT& _mesh,
02156 const Point& _p0,
02157 const Point& _p1,
02158 const typename MeshT::FaceHandle _fh0,
02159 const typename MeshT::FaceHandle _fh1,
02160 std::vector<Point> & _points,
02161 std::vector<typename MeshT::EdgeHandle>& _ehandles )
02162 {
02163
02164 _points.clear();
02165 _ehandles.clear();
02166
02167 Point p_start = _p0;
02168 Point p_end = _p1;
02169
02170 typename MeshT::FaceHandle fh_start = _fh0;
02171 typename MeshT::FaceHandle fh_end = _fh1;
02172
02173 if( fh_start == fh_end)
02174 return;
02175
02176
02177 std::vector<Point> new_points0, new_points1;
02178
02179
02180 std::vector<typename MeshT::EdgeHandle> new_eh0, new_eh1;
02181
02182
02183
02184
02185
02186
02187
02188 typename MeshT::HalfedgeHandle heh = _mesh.halfedge_handle(fh_start);
02189 Point p0 = (Point)_mesh.point(_mesh.to_vertex_handle( heh ));
02190 Point p1 = (Point)_mesh.point(_mesh.to_vertex_handle( heh = _mesh.next_halfedge_handle(heh) ));
02191 Point p2 = (Point)_mesh.point(_mesh.to_vertex_handle( heh = _mesh.next_halfedge_handle(heh) ));
02192 Point n_start = ((p1-p0)%(p2-p0)).normalize();
02193
02194
02195 heh = _mesh.halfedge_handle(fh_end);
02196 p0 = _mesh.point(_mesh.to_vertex_handle( heh ));
02197 p1 = _mesh.point(_mesh.to_vertex_handle( heh = _mesh.next_halfedge_handle(heh) ));
02198 p2 = _mesh.point(_mesh.to_vertex_handle( heh = _mesh.next_halfedge_handle(heh) ));
02199 Point n_end = ((p1-p0)%(p2-p0)).normalize();
02200
02201
02202 Point n_avg = n_start + n_end;
02203 if( n_avg.sqrnorm() < 1e-7) n_avg = n_start - n_end;
02204 n_avg.normalize();
02205
02206
02207 Point n_plane = n_avg % (p_start-p_end).normalize();
02208 if( n_plane.sqrnorm() > 1e-9) n_plane.normalize();
02209 else std::cerr << "WARNING: Edge Resampling -> not possible to construct stable cut plane!!!\n";
02210 Point p_plane = (p_start + p_end)*0.5;
02211
02212
02213 std::vector<typename MeshT::HalfedgeHandle > start_hehs;
02214 std::vector<Point> start_ps;
02215 heh = _mesh.halfedge_handle(fh_start);
02216 Point p_int;
02217 for(unsigned int i=0; i<3; ++i)
02218 {
02219
02220 p0 = (Point) _mesh.point(_mesh.from_vertex_handle(heh));
02221 p1 = (Point) _mesh.point(_mesh.to_vertex_handle (heh));
02222
02223
02224 if( plane_line_intersection( p_plane, n_plane, p0, p1, p_int))
02225 {
02226 start_hehs.push_back( heh );
02227 start_ps.push_back(p_int);
02228 }
02229
02230 heh = _mesh.next_halfedge_handle(heh);
02231 }
02232
02233
02234
02235 std::vector<typename MeshT::HalfedgeHandle > end_hehs;
02236 std::vector<Point> end_ps;
02237 heh = _mesh.halfedge_handle(fh_end);
02238 for(unsigned int i=0; i<3; ++i)
02239 {
02240
02241 p0 = (Point) _mesh.point(_mesh.from_vertex_handle(heh));
02242 p1 = (Point) _mesh.point(_mesh.to_vertex_handle (heh));
02243
02244
02245 if( plane_line_intersection( p_plane, n_plane, p0, p1, p_int))
02246 {
02247 end_hehs.push_back( heh );
02248 end_ps.push_back(p_int);
02249 }
02250
02251 heh = _mesh.next_halfedge_handle(heh);
02252 }
02253
02254
02255
02256 if( start_hehs.size() != 2 || end_hehs.size() != 2)
02257 {
02258 std::cerr << "PolyLineResampling ERROR: wrong number of intersections... ";
02259 std::cerr << start_hehs.size() << " ";
02260 std::cerr << end_hehs.size() << std::endl;
02261 }
02262
02263
02264
02265
02266 if( start_hehs.size() == 2 && end_hehs.size() == 2)
02267 {
02268
02269 typename MeshT::HalfedgeHandle cur_heh0 = start_hehs[0];
02270 typename MeshT::HalfedgeHandle cur_heh1 = start_hehs[1];
02271
02272
02273 new_points0.push_back( start_ps[0]);
02274 new_eh0.push_back( _mesh.edge_handle( cur_heh0));
02275
02276 new_points1.push_back( start_ps[1]);
02277 new_eh1.push_back( _mesh.edge_handle( cur_heh1));
02278
02279 unsigned int count = 0;
02280
02281 while( _mesh.face_handle(_mesh.opposite_halfedge_handle(cur_heh0)) != fh_end &&
02282 _mesh.face_handle(_mesh.opposite_halfedge_handle(cur_heh1)) != fh_end &&
02283 count < 1000 )
02284 {
02285 ++count;
02286
02287
02288 cur_heh0 = _mesh.opposite_halfedge_handle( cur_heh0);
02289
02290
02291 if( _mesh.is_boundary(cur_heh0))
02292 {
02293 std::cerr << "ERROR: found boundary in traversal!!!\n";
02294 cur_heh0 = _mesh.opposite_halfedge_handle( cur_heh0);
02295 } else {
02296
02297 unsigned int old_size = new_points0.size();
02298
02299 for(unsigned int i=0; i<2; ++i)
02300 {
02301
02302 cur_heh0 = _mesh.next_halfedge_handle(cur_heh0);
02303
02304
02305 p0 = (Point) _mesh.point(_mesh.from_vertex_handle(cur_heh0));
02306 p1 = (Point) _mesh.point(_mesh.to_vertex_handle (cur_heh0));
02307
02308
02309 if( plane_line_intersection( p_plane, n_plane, p0, p1, p_int))
02310 {
02311 new_points0.push_back(p_int);
02312 new_eh0.push_back( _mesh.edge_handle( cur_heh0));
02313 break;
02314 }
02315 }
02316
02317
02318 if( new_points0.size() != old_size + 1)
02319 std::cerr << "WARNING: could not find new point!!!\n";
02320 }
02321
02322
02323 cur_heh1 = _mesh.opposite_halfedge_handle( cur_heh1);
02324
02325
02326 if( _mesh.is_boundary(cur_heh1))
02327 {
02328 std::cerr << "ERROR: found boundary in traversal!!!\n";
02329 cur_heh1 = _mesh.opposite_halfedge_handle( cur_heh1);
02330 } else {
02331
02332 unsigned int old_size = new_points1.size();
02333
02334 for(unsigned int i=0; i<2; ++i)
02335 {
02336
02337 cur_heh1 = _mesh.next_halfedge_handle(cur_heh1);
02338
02339
02340 p0 = (Point) _mesh.point(_mesh.from_vertex_handle(cur_heh1));
02341 p1 = (Point) _mesh.point(_mesh.to_vertex_handle (cur_heh1));
02342
02343
02344 if( plane_line_intersection( p_plane, n_plane, p0, p1, p_int))
02345 {
02346 new_points1.push_back(p_int);
02347 new_eh1.push_back( _mesh.edge_handle( cur_heh1));
02348 break;
02349 }
02350 }
02351
02352
02353 if( new_points1.size() != old_size + 1)
02354 std::cerr << "WARNING: could not find new point!!!\n";
02355 }
02356
02357 }
02358
02359
02360
02361
02362
02363
02364 if(_mesh.face_handle(_mesh.opposite_halfedge_handle(cur_heh0)) == fh_end )
02365 {
02366
02367 _points = new_points0;
02368 _ehandles = new_eh0;
02369 }
02370 else
02371 if (_mesh.face_handle(_mesh.opposite_halfedge_handle(cur_heh1)) == fh_end)
02372 {
02373
02374 _points = new_points1;
02375 _ehandles = new_eh1;
02376 }
02377 }
02378 }
02379
02380
02381
02382 }
02383