52 #include "HoleFillerT.hh" 54 #include <QInputDialog> 56 template<
class MeshT >
60 mesh_.request_vertex_status();
61 mesh_.request_edge_status();
63 if (! mesh_.get_property_handle(scale_,
"scale") )
64 mesh_.add_property( scale_ ,
"scale" );
72 template<
class MeshT >
75 mesh_.release_vertex_status();
76 mesh_.release_edge_status();
78 if ( mesh_.get_property_handle(scale_,
"scale") )
79 mesh_.remove_property( scale_ );
90 template<
class MeshT >
96 std::vector< EH > bdry_edge;
98 for ( EI ei = mesh_.edges_begin();
99 ei != mesh_.edges_end(); ++ei )
100 if ( mesh_.is_boundary( *ei ) )
101 bdry_edge.push_back( *ei );
106 for (
typename std::vector< EH >::iterator i = bdry_edge.begin();
107 i != bdry_edge.end(); ++i )
108 if ( mesh_.is_boundary( *i ) )
111 std::cerr <<
"Filling hole " << cnt <<
"\n";
112 fill_hole( *i, _stages );
121 std::cerr <<
"Stage 3 : Smoothing the hole fillings ... ";
125 Tangential_and_Normal,
128 smoother.smooth( 500 );
140 template<
class MeshT >
144 std::cerr <<
" Stage 1 : Computing a minimal triangulation ... ";
147 typename MeshT::VertexHandle old_last_handle = *(--mesh_.vertices_end());
151 if ( ! mesh_.is_boundary( _eh ) )
157 HH hh = mesh_.halfedge_handle( _eh, 0 );
158 if ( ! mesh_.is_boundary( hh ) )
159 hh = mesh_.opposite_halfedge_handle( hh );
164 boundary_vertex_.clear();
165 opposite_vertex_.clear();
170 boundary_vertex_.push_back( mesh_.from_vertex_handle( ch ) );
171 opposite_vertex_.push_back( mesh_.to_vertex_handle
172 (mesh_.next_halfedge_handle( mesh_.opposite_halfedge_handle( ch ) ) ) );
176 VH vh = mesh_.to_vertex_handle(ch);
178 for (
typename MeshT::VertexOHalfedgeIter voh_it(mesh_,vh); voh_it.is_valid(); ++voh_it)
179 if ( mesh_.is_boundary( *voh_it ) )
183 HH op = mesh_.opposite_halfedge_handle( ch );
184 typename MeshT::VertexOHalfedgeIter voh_it(mesh_,op);
188 ch = mesh_.next_halfedge_handle( ch );
190 }
while ( ch != hh );
193 int nv = boundary_vertex_.size();
198 w_.resize( nv, std::vector<Weight>( nv, Weight() ) );
201 l_.resize( nv, std::vector<int>( nv, 0 ) );
204 for (
int i = 0; i < nv - 1; ++i )
205 w_[i][i+1] = Weight( 0, 0 );
207 for (
int j = 2; j < nv; ++j )
209 #pragma omp parallel for shared(j, nv) 210 for(
int i = 0; i < nv-j; ++i)
214 for (
int m = i + 1; m < i + j; ++m )
216 Weight newval = w_[i][m] + w_[m][i+j] + weight( i, m, i+j );
217 if ( newval < valmin )
234 hole_triangle_.clear();
235 if ( fill( 0, nv - 1 ) ){
242 std::cerr <<
" Stage 2 : Fairing the filling ... ";
244 std::vector< FH > handles = hole_triangle_;
249 typename MeshT::VertexIter old_end = ++
typename MeshT::VertexIter(mesh_,old_last_handle);
250 typename MeshT::VertexIter v_end = mesh_.vertices_end();
252 for(; old_end != v_end; ++old_end)
253 if ( !mesh_.status(*old_end).deleted() )
254 mesh_.status(*old_end).set_selected(
true );
258 std::cerr <<
"Could not create triangulation" << std::endl;
263 template<
class MeshT >
270 hole_triangle_ = _faceHandles;
277 if (! mesh_.get_property_handle(edgeProp,
"edgeProp") )
278 mesh_.add_property( edgeProp,
"edgeProp" );
279 if (! mesh_.get_property_handle(vertexProp,
"vertexProp") )
280 mesh_.add_property( vertexProp,
"vertexProp" );
281 if (! mesh_.get_property_handle(faceProp,
"faceProp") )
282 mesh_.add_property( faceProp,
"faceProp" );
283 if (! mesh_.get_property_handle(orderProp,
"orderProp") )
284 mesh_.add_property( orderProp,
"orderProp" );
287 EI eEnd = mesh_.edges_end();
289 VI vEnd = mesh_.vertices_end();
291 FI fEnd = mesh_.faces_end();
294 for (fIt = mesh_.faces_begin(); fIt != fEnd; ++fIt){
295 mesh_.property( orderProp, *fIt ) =
false;
296 mesh_.property( faceProp, *fIt ) =
false;
299 for (eIt = mesh_.edges_begin(); eIt != eEnd; ++eIt)
300 mesh_.property( edgeProp, *eIt ) =
false;
302 for (vIt = mesh_.vertices_begin(); vIt != vEnd; ++vIt){
303 mesh_.property( vertexProp, *vIt ) =
false;
307 for (uint i = 0; i < hole_triangle_.size(); i++){
308 mesh_.property( faceProp, hole_triangle_[i] ) =
true;
312 for (
unsigned int i = 0; i < hole_triangle_.size(); i++){
313 for (FEI fei = mesh_.fe_iter( hole_triangle_[i] ); fei.is_valid(); ++fei){
314 mesh_.status( *fei ).set_locked(
true);
316 if (mesh_.property( faceProp, mesh_.face_handle(mesh_.halfedge_handle(*fei, 0) ) ) &&
317 mesh_.property( faceProp, mesh_.face_handle(mesh_.halfedge_handle(*fei, 1) ) ) ){
319 mesh_.property( edgeProp, *fei ) =
true;
320 hole_edge_.push_back( *fei );
321 mesh_.status( *fei ).set_locked(
false);
326 for (FVI fvi = mesh_.fv_iter( hole_triangle_[i] ); fvi.is_valid(); ++fvi){
328 for ( VFI vfi = mesh_.vf_iter( *fvi ); vfi.is_valid(); ++vfi )
329 mesh_.property( vertexProp, *fvi ) =
true;
334 for (vIt = mesh_.vertices_begin(); vIt != vEnd; ++vIt)
335 if (mesh_.property(vertexProp, *vIt)){
340 for ( VOHI voh_it = mesh_.voh_iter( *vIt ); voh_it.is_valid(); ++voh_it )
342 HH h2 = mesh_.opposite_halfedge_handle( *voh_it );
344 if (mesh_.face_handle(*voh_it).is_valid() &&
345 mesh_.face_handle(h2).is_valid() &&
346 mesh_.property(faceProp, mesh_.face_handle( *voh_it ) ) &&
347 mesh_.property(faceProp, mesh_.face_handle(h2) ))
351 Point p0 = mesh_.point( *vIt );
352 Point p1 = mesh_.point( mesh_.to_vertex_handle( *voh_it ) );
353 scale += ( p1 - p0 ).norm();
359 mesh_.property( scale_, *vIt ) = scale;
362 mesh_.remove_property(edgeProp);
363 mesh_.remove_property(vertexProp);
364 mesh_.remove_property(faceProp);
365 mesh_.remove_property(orderProp);
369 bool did_refine =
true;
371 for (
int k = 0; k < 40 && did_refine; ++k )
373 uint end = hole_triangle_.size();
376 for (
unsigned int j = 0; j < end; ++j )
377 did_refine |= refine( hole_triangle_[j] );
379 for (
int i = 0; i < 10; ++i )
380 for (
unsigned int j = 0; j < hole_edge_.size(); ++j )
381 relax_edge( hole_edge_[j] );
385 for ( EI ei = mesh_.edges_begin(); ei != mesh_.edges_end(); ++ei )
386 mesh_.status( *ei ).set_locked(
false );
398 template<
class MeshT >
405 FEI fei = mesh_.fe_iter( _fh );
413 FVI fvi = mesh_.fv_iter( _fh );
419 Point p0 = mesh_.point( v0 );
420 Point p1 = mesh_.point( v1 );
421 Point p2 = mesh_.point( v2 );
423 Scalar scale0 = mesh_.property( scale_, v0 );
424 Scalar scale1 = mesh_.property( scale_, v1 );
425 Scalar scale2 = mesh_.property( scale_, v2 );
429 Scalar scale = ( scale0 + scale1 + scale2 ) / 3.0f;
430 Point center =
typename MeshT::Scalar(1.0/3.0) * ( p0 + p1 + p2 );
432 Scalar d0 = 1.0f * ( p0 - center ).norm();
433 Scalar d1 = 1.0f * ( p1 - center ).norm();
434 Scalar d2 = 1.0f * ( p2 - center ).norm();
438 if ( (d0 + d1 + d2) / 3.0f < scale)
return false;
444 if ( ( d0 > scale && d0 > scale0 ) ||
445 ( d1 > scale && d1 > scale1 ) ||
446 ( d2 > scale && d2 > scale2 ) )
451 mesh_.
split( _fh, ch );
455 for ( VFI vfi = mesh_.vf_iter( ch ); vfi.is_valid(); ++vfi )
457 hole_triangle_.push_back( *vfi );
461 for ( VEI vei = mesh_.ve_iter( ch ); vei.is_valid(); ++vei )
462 hole_edge_.push_back( *vei );
466 mesh_.property( scale_, ch ) = scale;
487 template<
class MeshT >
491 if ( mesh_.status( _eh ).locked() )
496 HH h0 = mesh_.halfedge_handle( _eh, 0 );
497 HH h1 = mesh_.halfedge_handle( _eh, 1 );
501 Point u( mesh_.point( mesh_.to_vertex_handle( h0 ) ) );
502 Point v( mesh_.point( mesh_.to_vertex_handle( h1 ) ) );
507 ( mesh_.to_vertex_handle
508 ( mesh_.next_halfedge_handle( h0 ) ) ) );
511 ( mesh_.to_vertex_handle
512 ( mesh_.next_halfedge_handle( h1 ) ) ) );
517 if ( in_circumsphere( a, u, v, b ) || in_circumsphere( b, u, v, a ) ){
518 if ( mesh_.is_flip_ok( _eh ) )
525 mesh_.status(_eh).set_selected(
true );
538 template<
class MeshT >
543 const Point & _c )
const 548 Scalar a00 = -2.0f * ( ab | _a );
549 Scalar a01 = -2.0f * ( ab | _b );
550 Scalar a02 = -2.0f * ( ab | _c );
551 Scalar b0 = _a.sqrnorm() - _b.sqrnorm();
553 Scalar a10 = -2.0f * ( ac | _a );
554 Scalar a11 = -2.0f * ( ac | _b );
555 Scalar a12 = -2.0f * ( ac | _c );
556 Scalar b1 = _a.sqrnorm() - _c.sqrnorm();
558 typename MeshT::Scalar alpha = -(-a11*a02+a01*a12-a12*b0+b1*a02+a11*b0-a01*b1)
559 / (-a11*a00+a11*a02-a10*a02+a00*a12+a01*a10-a01*a12);
560 typename MeshT::Scalar beta = (a10*b0-a10*a02-a12*b0+a00*a12+b1*a02-a00*b1)
561 / (-a11*a00+a11*a02-a10*a02+a00*a12+a01*a10-a01*a12);
562 typename MeshT::Scalar gamma = (-a11*a00-a10*b0+a00*b1+a11*b0+a01*a10-a01*b1)
563 / (-a11*a00+a11*a02-a10*a02+a00*a12+a01*a10-a01*a12);
565 Point center = alpha * _a + beta * _b + gamma * _c;
567 return ( _x - center ).sqrnorm() < ( _a - center ).sqrnorm();
580 template<
class MeshT >
592 FH fh = mesh_.add_face( boundary_vertex_[_i],
593 boundary_vertex_[ l_[_i][_j] ],
594 boundary_vertex_[_j] );
595 hole_triangle_.push_back( fh );
600 hole_edge_.push_back( mesh_.edge_handle
601 ( mesh_.find_halfedge( boundary_vertex_[_i],
602 boundary_vertex_[ l_[_i][_j] ] ) ) );
603 hole_edge_.push_back( mesh_.edge_handle
604 ( mesh_.find_halfedge( boundary_vertex_[ l_[_i][_j] ],
605 boundary_vertex_[_j] ) ) );
611 if (!fill( _i, l_[_i][_j] ) || !fill( l_[_i][_j], _j ))
626 template<
class MeshT >
633 if ( exists_edge( boundary_vertex_[_i], boundary_vertex_[_j] ) ||
634 exists_edge( boundary_vertex_[_j], boundary_vertex_[_k] ) ||
635 exists_edge( boundary_vertex_[_k], boundary_vertex_[_i] ) )
643 if ( l_[_i][_j] == -1 )
return Weight();
644 if ( l_[_j][_k] == -1 )
return Weight();
653 angle = std::max( angle, dihedral_angle( boundary_vertex_[_i],
654 boundary_vertex_[_j],
655 boundary_vertex_[_k],
656 opposite_vertex_[_i] ) );
658 angle = std::max( angle, dihedral_angle( boundary_vertex_[_i],
659 boundary_vertex_[_j],
660 boundary_vertex_[_k],
661 boundary_vertex_[l_[_i][_j]] ) );
664 angle = std::max( angle, dihedral_angle( boundary_vertex_[_j],
665 boundary_vertex_[_k],
666 boundary_vertex_[_i],
667 opposite_vertex_[_j] ) );
669 angle = std::max( angle, dihedral_angle( boundary_vertex_[_j],
670 boundary_vertex_[_k],
671 boundary_vertex_[_i],
672 boundary_vertex_[l_[_j][_k]] ) );
674 if ( _i == 0 && _k == (
int) boundary_vertex_.size() - 1 )
675 angle = std::max( angle, dihedral_angle( boundary_vertex_[_k],
676 boundary_vertex_[_i],
677 boundary_vertex_[_j],
678 opposite_vertex_[_k] ) );
681 return Weight( angle, area( boundary_vertex_[_i],
682 boundary_vertex_[_j],
683 boundary_vertex_[_k] ) );
695 template<
class MeshT >
699 for ( VOHI vohi = mesh_.voh_iter( _u ); vohi.is_valid(); ++vohi )
700 if ( ! mesh_.is_boundary( mesh_.edge_handle( *vohi ) ) )
701 if ( mesh_.to_vertex_handle( *vohi ) == _w )
716 template<
class MeshT >
717 typename MeshT::Scalar
720 Point a( mesh_.point( _a ) );
721 Point b( mesh_.point( _b ) );
722 Point c( mesh_.point( _c ) );
724 Point n( ( b - a ) % ( c - b ) );
726 return 0.5 * n.norm();
741 template<
class MeshT >
742 typename MeshT::Scalar
745 Point u( mesh_.point( _u ) );
746 Point v( mesh_.point( _v ) );
747 Point a( mesh_.point( _a ) );
748 Point b( mesh_.point( _b ) );
750 Point n0( ( v - u ) % ( a - v ) );
751 Point n1( ( u - v ) % ( b - u ) );
756 return acos( n0 | n1 ) * 180.0 / M_PI;
761 template<
class MeshT >
765 for (
int i = _faceHandles.size()-1; i >= 0 ; i--){
767 if ( mesh_.status( _faceHandles[i] ).deleted() ){
770 _faceHandles.erase( _faceHandles.begin() + i );
775 FVI fvi = mesh_.fv_iter( _faceHandles[i] );
776 Point v0 = mesh_.point( *fvi);
778 Point v1 = mesh_.point( *fvi );
780 Point v2 = mesh_.point( *fvi );
783 Point v0v1 = v1 - v0;
784 Point v0v2 = v2 - v0;
785 Point n = v0v1 % v0v2;
786 double d = n.sqrnorm();
788 if (d < FLT_MIN && d > -FLT_MIN) {
790 FHI hIt = mesh_.fh_iter( _faceHandles[i] );
793 while (hIt.is_valid()){
794 if ( mesh_.is_collapse_ok( *hIt ) ){
796 mesh_.collapse( *hIt );
798 _faceHandles.erase( _faceHandles.begin() + i );
T angle(T _cos_angle, T _sin_angle)
VertexHandle split(EdgeHandle _eh, const Point &_p)
Edge split (= 2-to-4 split)
VertexHandle add_vertex(const Point &_p)
Alias for new_vertex(const Point&).