46 #include "HoleFillerT.hh" 48 #include <QInputDialog> 50 template<
class MeshT >
54 mesh_.request_vertex_status();
55 mesh_.request_edge_status();
57 if (! mesh_.get_property_handle(scale_,
"scale") )
58 mesh_.add_property( scale_ ,
"scale" );
66 template<
class MeshT >
69 mesh_.release_vertex_status();
70 mesh_.release_edge_status();
72 if ( mesh_.get_property_handle(scale_,
"scale") )
73 mesh_.remove_property( scale_ );
84 template<
class MeshT >
90 std::vector< EH > bdry_edge;
92 for ( EI ei = mesh_.edges_begin();
93 ei != mesh_.edges_end(); ++ei )
94 if ( mesh_.is_boundary( *ei ) )
95 bdry_edge.push_back( *ei );
100 for (
typename std::vector< EH >::iterator i = bdry_edge.begin();
101 i != bdry_edge.end(); ++i )
102 if ( mesh_.is_boundary( *i ) )
105 std::cerr <<
"Filling hole " << cnt <<
"\n";
106 fill_hole( *i, _stages );
115 std::cerr <<
"Stage 3 : Smoothing the hole fillings ... ";
119 Tangential_and_Normal,
122 smoother.smooth( 500 );
134 template<
class MeshT >
138 std::cerr <<
" Stage 1 : Computing a minimal triangulation ... ";
141 typename MeshT::VertexHandle old_last_handle = *(--mesh_.vertices_end());
145 if ( ! mesh_.is_boundary( _eh ) )
151 HH hh = mesh_.halfedge_handle( _eh, 0 );
152 if ( ! mesh_.is_boundary( hh ) )
153 hh = mesh_.opposite_halfedge_handle( hh );
158 boundary_vertex_.clear();
159 opposite_vertex_.clear();
164 boundary_vertex_.push_back( mesh_.from_vertex_handle( ch ) );
165 opposite_vertex_.push_back( mesh_.to_vertex_handle
166 (mesh_.next_halfedge_handle( mesh_.opposite_halfedge_handle( ch ) ) ) );
170 VH vh = mesh_.to_vertex_handle(ch);
172 for (
typename MeshT::VertexOHalfedgeIter voh_it(mesh_,vh); voh_it.is_valid(); ++voh_it)
173 if ( mesh_.is_boundary( *voh_it ) )
177 HH op = mesh_.opposite_halfedge_handle( ch );
178 typename MeshT::VertexOHalfedgeIter voh_it(mesh_,op);
182 ch = mesh_.next_halfedge_handle( ch );
184 }
while ( ch != hh );
187 int nv = boundary_vertex_.size();
192 w_.resize( nv, std::vector<Weight>( nv, Weight() ) );
195 l_.resize( nv, std::vector<int>( nv, 0 ) );
198 for (
int i = 0; i < nv - 1; ++i )
199 w_[i][i+1] = Weight( 0, 0 );
201 for (
int j = 2; j < nv; ++j )
203 #pragma omp parallel for shared(j, nv) 204 for(
int i = 0; i < nv-j; ++i)
208 for (
int m = i + 1; m < i + j; ++m )
210 Weight newval = w_[i][m] + w_[m][i+j] + weight( i, m, i+j );
211 if ( newval < valmin )
228 hole_triangle_.clear();
229 if ( fill( 0, nv - 1 ) ){
236 std::cerr <<
" Stage 2 : Fairing the filling ... ";
238 std::vector< FH > handles = hole_triangle_;
243 typename MeshT::VertexIter old_end = ++
typename MeshT::VertexIter(mesh_,old_last_handle);
244 typename MeshT::VertexIter v_end = mesh_.vertices_end();
246 for(; old_end != v_end; ++old_end)
247 if ( !mesh_.status(*old_end).deleted() )
248 mesh_.status(*old_end).set_selected(
true );
252 std::cerr <<
"Could not create triangulation" << std::endl;
257 template<
class MeshT >
264 hole_triangle_ = _faceHandles;
271 if (! mesh_.get_property_handle(edgeProp,
"edgeProp") )
272 mesh_.add_property( edgeProp,
"edgeProp" );
273 if (! mesh_.get_property_handle(vertexProp,
"vertexProp") )
274 mesh_.add_property( vertexProp,
"vertexProp" );
275 if (! mesh_.get_property_handle(faceProp,
"faceProp") )
276 mesh_.add_property( faceProp,
"faceProp" );
277 if (! mesh_.get_property_handle(orderProp,
"orderProp") )
278 mesh_.add_property( orderProp,
"orderProp" );
281 EI eEnd = mesh_.edges_end();
283 VI vEnd = mesh_.vertices_end();
285 FI fEnd = mesh_.faces_end();
288 for (fIt = mesh_.faces_begin(); fIt != fEnd; ++fIt){
289 mesh_.property( orderProp, *fIt ) =
false;
290 mesh_.property( faceProp, *fIt ) =
false;
293 for (eIt = mesh_.edges_begin(); eIt != eEnd; ++eIt)
294 mesh_.property( edgeProp, *eIt ) =
false;
296 for (vIt = mesh_.vertices_begin(); vIt != vEnd; ++vIt){
297 mesh_.property( vertexProp, *vIt ) =
false;
301 for (uint i = 0; i < hole_triangle_.size(); i++){
302 mesh_.property( faceProp, hole_triangle_[i] ) =
true;
306 for (
unsigned int i = 0; i < hole_triangle_.size(); i++){
307 for (FEI fei = mesh_.fe_iter( hole_triangle_[i] ); fei.is_valid(); ++fei){
308 mesh_.status( *fei ).set_locked(
true);
310 if (mesh_.property( faceProp, mesh_.face_handle(mesh_.halfedge_handle(*fei, 0) ) ) &&
311 mesh_.property( faceProp, mesh_.face_handle(mesh_.halfedge_handle(*fei, 1) ) ) ){
313 mesh_.property( edgeProp, *fei ) =
true;
314 hole_edge_.push_back( *fei );
315 mesh_.status( *fei ).set_locked(
false);
320 for (FVI fvi = mesh_.fv_iter( hole_triangle_[i] ); fvi.is_valid(); ++fvi){
322 for ( VFI vfi = mesh_.vf_iter( *fvi ); vfi.is_valid(); ++vfi )
323 mesh_.property( vertexProp, *fvi ) =
true;
328 for (vIt = mesh_.vertices_begin(); vIt != vEnd; ++vIt)
329 if (mesh_.property(vertexProp, *vIt)){
334 for ( VOHI voh_it = mesh_.voh_iter( *vIt ); voh_it.is_valid(); ++voh_it )
336 HH h2 = mesh_.opposite_halfedge_handle( *voh_it );
338 if (mesh_.face_handle(*voh_it).is_valid() &&
339 mesh_.face_handle(h2).is_valid() &&
340 mesh_.property(faceProp, mesh_.face_handle( *voh_it ) ) &&
341 mesh_.property(faceProp, mesh_.face_handle(h2) ))
345 Point p0 = mesh_.point( *vIt );
346 Point p1 = mesh_.point( mesh_.to_vertex_handle( *voh_it ) );
347 scale += ( p1 - p0 ).norm();
353 mesh_.property( scale_, *vIt ) = scale;
356 mesh_.remove_property(edgeProp);
357 mesh_.remove_property(vertexProp);
358 mesh_.remove_property(faceProp);
359 mesh_.remove_property(orderProp);
363 bool did_refine =
true;
365 for (
int k = 0; k < 40 && did_refine; ++k )
367 uint end = hole_triangle_.size();
370 for (
unsigned int j = 0; j < end; ++j )
371 did_refine |= refine( hole_triangle_[j] );
373 for (
int i = 0; i < 10; ++i )
374 for (
unsigned int j = 0; j < hole_edge_.size(); ++j )
375 relax_edge( hole_edge_[j] );
379 for ( EI ei = mesh_.edges_begin(); ei != mesh_.edges_end(); ++ei )
380 mesh_.status( *ei ).set_locked(
false );
392 template<
class MeshT >
399 FEI fei = mesh_.fe_iter( _fh );
407 FVI fvi = mesh_.fv_iter( _fh );
413 Point p0 = mesh_.point( v0 );
414 Point p1 = mesh_.point( v1 );
415 Point p2 = mesh_.point( v2 );
417 Scalar scale0 = mesh_.property( scale_, v0 );
418 Scalar scale1 = mesh_.property( scale_, v1 );
419 Scalar scale2 = mesh_.property( scale_, v2 );
423 Scalar scale = ( scale0 + scale1 + scale2 ) / 3.0f;
424 Point center =
typename MeshT::Scalar(1.0/3.0) * ( p0 + p1 + p2 );
426 Scalar d0 = 1.0f * ( p0 - center ).norm();
427 Scalar d1 = 1.0f * ( p1 - center ).norm();
428 Scalar d2 = 1.0f * ( p2 - center ).norm();
432 if ( (d0 + d1 + d2) / 3.0f < scale)
return false;
438 if ( ( d0 > scale && d0 > scale0 ) ||
439 ( d1 > scale && d1 > scale1 ) ||
440 ( d2 > scale && d2 > scale2 ) )
445 mesh_.
split( _fh, ch );
449 for ( VFI vfi = mesh_.vf_iter( ch ); vfi.is_valid(); ++vfi )
451 hole_triangle_.push_back( *vfi );
455 for ( VEI vei = mesh_.ve_iter( ch ); vei.is_valid(); ++vei )
456 hole_edge_.push_back( *vei );
460 mesh_.property( scale_, ch ) = scale;
481 template<
class MeshT >
485 if ( mesh_.status( _eh ).locked() )
490 HH h0 = mesh_.halfedge_handle( _eh, 0 );
491 HH h1 = mesh_.halfedge_handle( _eh, 1 );
495 Point u( mesh_.point( mesh_.to_vertex_handle( h0 ) ) );
496 Point v( mesh_.point( mesh_.to_vertex_handle( h1 ) ) );
501 ( mesh_.to_vertex_handle
502 ( mesh_.next_halfedge_handle( h0 ) ) ) );
505 ( mesh_.to_vertex_handle
506 ( mesh_.next_halfedge_handle( h1 ) ) ) );
511 if ( in_circumsphere( a, u, v, b ) || in_circumsphere( b, u, v, a ) ){
512 if ( mesh_.is_flip_ok( _eh ) )
519 mesh_.status(_eh).set_selected(
true );
532 template<
class MeshT >
537 const Point & _c )
const 542 Scalar a00 = -2.0f * ( ab | _a );
543 Scalar a01 = -2.0f * ( ab | _b );
544 Scalar a02 = -2.0f * ( ab | _c );
545 Scalar b0 = _a.sqrnorm() - _b.sqrnorm();
547 Scalar a10 = -2.0f * ( ac | _a );
548 Scalar a11 = -2.0f * ( ac | _b );
549 Scalar a12 = -2.0f * ( ac | _c );
550 Scalar b1 = _a.sqrnorm() - _c.sqrnorm();
552 typename MeshT::Scalar alpha = -(-a11*a02+a01*a12-a12*b0+b1*a02+a11*b0-a01*b1)
553 / (-a11*a00+a11*a02-a10*a02+a00*a12+a01*a10-a01*a12);
554 typename MeshT::Scalar beta = (a10*b0-a10*a02-a12*b0+a00*a12+b1*a02-a00*b1)
555 / (-a11*a00+a11*a02-a10*a02+a00*a12+a01*a10-a01*a12);
556 typename MeshT::Scalar gamma = (-a11*a00-a10*b0+a00*b1+a11*b0+a01*a10-a01*b1)
557 / (-a11*a00+a11*a02-a10*a02+a00*a12+a01*a10-a01*a12);
559 Point center = alpha * _a + beta * _b + gamma * _c;
561 return ( _x - center ).sqrnorm() < ( _a - center ).sqrnorm();
574 template<
class MeshT >
586 FH fh = mesh_.add_face( boundary_vertex_[_i],
587 boundary_vertex_[ l_[_i][_j] ],
588 boundary_vertex_[_j] );
589 hole_triangle_.push_back( fh );
594 hole_edge_.push_back( mesh_.edge_handle
595 ( mesh_.find_halfedge( boundary_vertex_[_i],
596 boundary_vertex_[ l_[_i][_j] ] ) ) );
597 hole_edge_.push_back( mesh_.edge_handle
598 ( mesh_.find_halfedge( boundary_vertex_[ l_[_i][_j] ],
599 boundary_vertex_[_j] ) ) );
605 if (!fill( _i, l_[_i][_j] ) || !fill( l_[_i][_j], _j ))
620 template<
class MeshT >
627 if ( exists_edge( boundary_vertex_[_i], boundary_vertex_[_j] ) ||
628 exists_edge( boundary_vertex_[_j], boundary_vertex_[_k] ) ||
629 exists_edge( boundary_vertex_[_k], boundary_vertex_[_i] ) )
637 if ( l_[_i][_j] == -1 )
return Weight();
638 if ( l_[_j][_k] == -1 )
return Weight();
647 angle = std::max( angle, dihedral_angle( boundary_vertex_[_i],
648 boundary_vertex_[_j],
649 boundary_vertex_[_k],
650 opposite_vertex_[_i] ) );
652 angle = std::max( angle, dihedral_angle( boundary_vertex_[_i],
653 boundary_vertex_[_j],
654 boundary_vertex_[_k],
655 boundary_vertex_[l_[_i][_j]] ) );
658 angle = std::max( angle, dihedral_angle( boundary_vertex_[_j],
659 boundary_vertex_[_k],
660 boundary_vertex_[_i],
661 opposite_vertex_[_j] ) );
663 angle = std::max( angle, dihedral_angle( boundary_vertex_[_j],
664 boundary_vertex_[_k],
665 boundary_vertex_[_i],
666 boundary_vertex_[l_[_j][_k]] ) );
668 if ( _i == 0 && _k == (
int) boundary_vertex_.size() - 1 )
669 angle = std::max( angle, dihedral_angle( boundary_vertex_[_k],
670 boundary_vertex_[_i],
671 boundary_vertex_[_j],
672 opposite_vertex_[_k] ) );
675 return Weight( angle, area( boundary_vertex_[_i],
676 boundary_vertex_[_j],
677 boundary_vertex_[_k] ) );
689 template<
class MeshT >
693 for ( VOHI vohi = mesh_.voh_iter( _u ); vohi.is_valid(); ++vohi )
694 if ( ! mesh_.is_boundary( mesh_.edge_handle( *vohi ) ) )
695 if ( mesh_.to_vertex_handle( *vohi ) == _w )
710 template<
class MeshT >
711 typename MeshT::Scalar
714 Point a( mesh_.point( _a ) );
715 Point b( mesh_.point( _b ) );
716 Point c( mesh_.point( _c ) );
718 Point n( ( b - a ) % ( c - b ) );
720 return 0.5 * n.norm();
735 template<
class MeshT >
736 typename MeshT::Scalar
739 Point u( mesh_.point( _u ) );
740 Point v( mesh_.point( _v ) );
741 Point a( mesh_.point( _a ) );
742 Point b( mesh_.point( _b ) );
744 Point n0( ( v - u ) % ( a - v ) );
745 Point n1( ( u - v ) % ( b - u ) );
750 return acos( n0 | n1 ) * 180.0 / M_PI;
755 template<
class MeshT >
759 for (
int i = _faceHandles.size()-1; i >= 0 ; i--){
761 if ( mesh_.status( _faceHandles[i] ).deleted() ){
764 _faceHandles.erase( _faceHandles.begin() + i );
769 FVI fvi = mesh_.fv_iter( _faceHandles[i] );
770 Point v0 = mesh_.point( *fvi);
772 Point v1 = mesh_.point( *fvi );
774 Point v2 = mesh_.point( *fvi );
777 Point v0v1 = v1 - v0;
778 Point v0v2 = v2 - v0;
779 Point n = v0v1 % v0v2;
780 double d = n.sqrnorm();
782 if (d < FLT_MIN && d > -FLT_MIN) {
784 FHI hIt = mesh_.fh_iter( _faceHandles[i] );
787 while (hIt.is_valid()){
788 if ( mesh_.is_collapse_ok( *hIt ) ){
790 mesh_.collapse( *hIt );
792 _faceHandles.erase( _faceHandles.begin() + i );
VertexHandle add_vertex(const Point &_p)
Alias for new_vertex(const Point&).
VertexHandle split(EdgeHandle _eh, const Point &_p)
Edge split (= 2-to-4 split)