Simplified Holefiller tests and more cleanup
This commit is contained in:
@@ -13,6 +13,11 @@
|
|||||||
<li>Update Doxygen config format</li>
|
<li>Update Doxygen config format</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<b>Tools</b>
|
||||||
|
<ul>
|
||||||
|
<li>HoleFiller: Added a simple Holefilling algorith.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
<b>IO</b>
|
<b>IO</b>
|
||||||
<ul>
|
<ul>
|
||||||
<li>PLY reader/writer: Fixed color trait Vec3f compilation for PLY writer</li>
|
<li>PLY reader/writer: Fixed color trait Vec3f compilation for PLY writer</li>
|
||||||
|
|||||||
@@ -61,23 +61,31 @@ public:
|
|||||||
explicit HoleFiller( MeshT & _mesh );
|
explicit HoleFiller( MeshT & _mesh );
|
||||||
~HoleFiller();
|
~HoleFiller();
|
||||||
|
|
||||||
// Identify and fill all holes of the mesh.
|
/** Identify and fill all holes of the mesh.
|
||||||
|
*
|
||||||
|
*/
|
||||||
void fill_all_holes( int _stages = 3 );
|
void fill_all_holes( int _stages = 3 );
|
||||||
|
|
||||||
|
|
||||||
// Fill a hole which is identified by one of its boundary edges.
|
/** Fill a hole which is identified by one of its boundary edges.
|
||||||
|
*
|
||||||
|
* @param _eh Edge Handle of a boundary halfedge at a hole that should be filled
|
||||||
|
* @param _stages If not set to 3, tha algorithm will abort after the given stage
|
||||||
|
*
|
||||||
|
*/
|
||||||
void fill_hole( typename MeshT::EdgeHandle _eh, int _stages = 3 );
|
void fill_hole( typename MeshT::EdgeHandle _eh, int _stages = 3 );
|
||||||
|
|
||||||
// Fair a filling
|
|
||||||
//void fairing( std::vector< FH >& _faceHandles );
|
|
||||||
void fairing( std::vector< OpenMesh::SmartFaceHandle >& _faceHandles );
|
|
||||||
|
|
||||||
// Remove degenerated faces from the filling
|
|
||||||
void removeDegeneratedFaces( std::vector< typename MeshT::FaceHandle >& _faceHandles );
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
||||||
|
void fairing( std::vector< OpenMesh::SmartFaceHandle >& _faceHandles );
|
||||||
|
|
||||||
|
// Remove degenerated faces from the filling
|
||||||
|
void removeDegeneratedFaces( std::vector< typename MeshT::FaceHandle >& _faceHandles );
|
||||||
|
|
||||||
// A weight is a tuple of area and maximum dihedral angle
|
// A weight is a tuple of area and maximum dihedral angle
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|||||||
@@ -90,32 +90,31 @@ template< class MeshT >
|
|||||||
void
|
void
|
||||||
HoleFiller< MeshT >::fill_all_holes( int _stages )
|
HoleFiller< MeshT >::fill_all_holes( int _stages )
|
||||||
{
|
{
|
||||||
// Collect all boundary edges
|
|
||||||
|
|
||||||
|
|
||||||
|
// Collect all boundary edges
|
||||||
std::vector< typename MeshT::EdgeHandle > bdry_edge;
|
std::vector< typename MeshT::EdgeHandle > bdry_edge;
|
||||||
|
|
||||||
for (auto ei : mesh_.edges())
|
for (auto ei : mesh_.edges())
|
||||||
if ( ei.is_boundary() )
|
if ( ei.is_boundary() )
|
||||||
bdry_edge.push_back( ei );
|
bdry_edge.push_back( ei );
|
||||||
|
|
||||||
// Fill holes
|
|
||||||
|
|
||||||
|
// Fill holes
|
||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
for (auto i : bdry_edge)
|
for (auto i : bdry_edge)
|
||||||
if ( mesh_.is_boundary( i ) )
|
if ( mesh_.is_boundary( i ) )
|
||||||
{
|
{
|
||||||
++cnt;
|
++cnt;
|
||||||
std::cerr << "Filling hole " << cnt << "\n";
|
omlog() << "Filling hole " << cnt << "\n";
|
||||||
fill_hole( i, _stages );
|
fill_hole( i, _stages );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Smooth fillings
|
// Smooth fillings
|
||||||
|
|
||||||
if ( _stages <= 2 )
|
if ( _stages <= 2 )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::cerr << "Stage 3 : Smoothing the hole fillings ... ";
|
omlog() << "Stage 3 : Smoothing the hole fillings ... ";
|
||||||
|
|
||||||
OpenMesh::Smoother::JacobiLaplaceSmootherT< MeshT > smoother( mesh_ );
|
OpenMesh::Smoother::JacobiLaplaceSmootherT< MeshT > smoother( mesh_ );
|
||||||
smoother.initialize( OpenMesh::Smoother::SmootherT< MeshT >::
|
smoother.initialize( OpenMesh::Smoother::SmootherT< MeshT >::
|
||||||
@@ -123,7 +122,6 @@ HoleFiller< MeshT >::fill_all_holes( int _stages )
|
|||||||
OpenMesh::Smoother::SmootherT< MeshT >::C1 );
|
OpenMesh::Smoother::SmootherT< MeshT >::C1 );
|
||||||
|
|
||||||
smoother.smooth( 500 );
|
smoother.smooth( 500 );
|
||||||
std::cerr << "ok\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -138,27 +136,25 @@ template< class MeshT >
|
|||||||
void
|
void
|
||||||
HoleFiller< MeshT >::fill_hole(typename MeshT::EdgeHandle _eh, int _stages )
|
HoleFiller< MeshT >::fill_hole(typename MeshT::EdgeHandle _eh, int _stages )
|
||||||
{
|
{
|
||||||
std::cerr << " Stage 1 : Computing a minimal triangulation ... ";
|
|
||||||
|
|
||||||
//remember last vertex for selection of new ones
|
omlog() << " Stage 1 : Computing a minimal triangulation ... ";
|
||||||
|
|
||||||
|
// remember last vertex for selection of new ones
|
||||||
typename MeshT::VertexHandle old_last_handle = *(--mesh_.vertices_end());
|
typename MeshT::VertexHandle old_last_handle = *(--mesh_.vertices_end());
|
||||||
|
|
||||||
// No boundary edge, no hole
|
// No boundary edge, no hole
|
||||||
|
if ( ! mesh_.is_boundary( _eh ) ) {
|
||||||
if ( ! mesh_.is_boundary( _eh ) )
|
omerr() << "fill_hole: Given edge handle is not a boundary edge at a hole!" << std::endl;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Get boundary halfedge
|
// Get boundary halfedge
|
||||||
|
|
||||||
OpenMesh::SmartHalfedgeHandle hh = make_smart(_eh, mesh_).h0();
|
OpenMesh::SmartHalfedgeHandle hh = make_smart(_eh, mesh_).h0();
|
||||||
|
|
||||||
if ( ! hh.is_boundary() )
|
if ( ! hh.is_boundary() )
|
||||||
hh = hh.opp();
|
hh = hh.opp();
|
||||||
|
|
||||||
|
|
||||||
// Collect boundary vertices
|
// Collect boundary vertices
|
||||||
|
|
||||||
boundary_vertex_.clear();
|
boundary_vertex_.clear();
|
||||||
opposite_vertex_.clear();
|
opposite_vertex_.clear();
|
||||||
|
|
||||||
@@ -189,7 +185,6 @@ HoleFiller< MeshT >::fill_hole(typename MeshT::EdgeHandle _eh, int _stages )
|
|||||||
int nv = boundary_vertex_.size();
|
int nv = boundary_vertex_.size();
|
||||||
|
|
||||||
// Compute an initial triangulation
|
// Compute an initial triangulation
|
||||||
|
|
||||||
w_.clear();
|
w_.clear();
|
||||||
w_.resize( nv, std::vector<Weight>( nv, Weight() ) );
|
w_.resize( nv, std::vector<Weight>( nv, Weight() ) );
|
||||||
|
|
||||||
@@ -222,20 +217,16 @@ HoleFiller< MeshT >::fill_hole(typename MeshT::EdgeHandle _eh, int _stages )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Actually fill the hole. We collect all triangles and edges of
|
// Actually fill the hole. We collect all triangles and edges of
|
||||||
// this filling for further processing.
|
// this filling for further processing.
|
||||||
|
|
||||||
hole_edge_.clear();
|
hole_edge_.clear();
|
||||||
hole_triangle_.clear();
|
hole_triangle_.clear();
|
||||||
if ( fill( 0, nv - 1 ) ){
|
if ( fill( 0, nv - 1 ) ){
|
||||||
|
|
||||||
std::cerr << "ok\n";
|
|
||||||
|
|
||||||
if ( _stages <= 1 )
|
if ( _stages <= 1 )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::cerr << " Stage 2 : Fairing the filling ... ";
|
omlog() << " Stage 2 : Fairing the filling ... " << std::endl;
|
||||||
|
|
||||||
std::vector< OpenMesh::SmartFaceHandle > handles = hole_triangle_;
|
std::vector< OpenMesh::SmartFaceHandle > handles = hole_triangle_;
|
||||||
|
|
||||||
@@ -249,9 +240,8 @@ HoleFiller< MeshT >::fill_hole(typename MeshT::EdgeHandle _eh, int _stages )
|
|||||||
if ( !mesh_.status(*old_end).deleted() )
|
if ( !mesh_.status(*old_end).deleted() )
|
||||||
mesh_.status(*old_end).set_selected( true );
|
mesh_.status(*old_end).set_selected( true );
|
||||||
|
|
||||||
std::cerr << "ok\n";
|
|
||||||
}else
|
}else
|
||||||
std::cerr << "Could not create triangulation" << std::endl;
|
omerr() << "Could not create triangulation" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -353,7 +343,6 @@ HoleFiller< MeshT >::fairing( std::vector< OpenMesh::SmartFaceHandle >& _faceHan
|
|||||||
mesh_.remove_property(orderProp);
|
mesh_.remove_property(orderProp);
|
||||||
|
|
||||||
// Do the patch fairing
|
// Do the patch fairing
|
||||||
|
|
||||||
bool did_refine = true;
|
bool did_refine = true;
|
||||||
|
|
||||||
for ( int k = 0; k < 40 && did_refine; ++k )
|
for ( int k = 0; k < 40 && did_refine; ++k )
|
||||||
|
|||||||
Binary file not shown.
@@ -43,8 +43,8 @@ TEST_F(OpenMeshHoleFiller_Triangle,Triangle_Hole_Filling) {
|
|||||||
ASSERT_TRUE(ok);
|
ASSERT_TRUE(ok);
|
||||||
|
|
||||||
// Check setup
|
// Check setup
|
||||||
EXPECT_EQ(7050u, mesh_.n_vertices() ) << "Wrong number of vertices";
|
EXPECT_EQ(5219u, mesh_.n_vertices() ) << "Wrong number of vertices";
|
||||||
EXPECT_EQ(13996u, mesh_.n_faces() ) << "Wrong number of faces";
|
EXPECT_EQ(10369u, mesh_.n_faces() ) << "Wrong number of faces";
|
||||||
|
|
||||||
|
|
||||||
// Initialize subdivider
|
// Initialize subdivider
|
||||||
@@ -55,8 +55,8 @@ TEST_F(OpenMeshHoleFiller_Triangle,Triangle_Hole_Filling) {
|
|||||||
filler.fill_all_holes();
|
filler.fill_all_holes();
|
||||||
|
|
||||||
|
|
||||||
EXPECT_EQ(7353u, mesh_.n_vertices() ) << "Wrong number of vertices after smoothing?";
|
EXPECT_EQ(5330u, mesh_.n_vertices() ) << "Wrong number of vertices after smoothing?";
|
||||||
EXPECT_EQ(14702u, mesh_.n_faces() ) << "Wrong number of faces after smoothing?";
|
EXPECT_EQ(10656u, mesh_.n_faces() ) << "Wrong number of faces after smoothing?";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user