mirror of https://github.com/CGAL/cgal
force_manifold and separate_shells attributes replaced by parameters for clearer interface
This commit is contained in:
parent
fb7b5d7884
commit
644df25e9e
|
|
@ -37,11 +37,13 @@ int main(int argc, char* argv[]) {
|
|||
Timer t;
|
||||
t.start();
|
||||
// Construct the mesh in a scale space.
|
||||
Reconstruction reconstruct( 10, 200,
|
||||
false, // Do not separate shells
|
||||
true // Force manifold output
|
||||
);
|
||||
reconstruct.reconstruct_surface( points.begin(), points.end(), 4 );
|
||||
Reconstruction reconstruct( 10, 200 );
|
||||
|
||||
reconstruct.reconstruct_surface( points.begin(), points.end(), 4,
|
||||
false, // Do not separate shells
|
||||
true // Force manifold output
|
||||
);
|
||||
|
||||
std::cerr << "Reconstruction done in " << t.time() << " sec." << std::endl;
|
||||
t.reset();
|
||||
std::ofstream out ("out.off");
|
||||
|
|
|
|||
|
|
@ -201,17 +201,13 @@ public:
|
|||
|
||||
template < class Gt, class FS, class wA, class Ct >
|
||||
Scale_space_surface_reconstruction_3<Gt,FS,wA,Ct>::
|
||||
Scale_space_surface_reconstruction_3( unsigned int neighbors, unsigned int samples,
|
||||
bool separate_shells, bool force_manifold)
|
||||
: _generator (0),_mean_neighbors(neighbors), _samples(samples), _squared_radius(-1),
|
||||
_separate_shells (separate_shells), _force_manifold (force_manifold),
|
||||
_border_angle (45.), _shape(0) {}
|
||||
Scale_space_surface_reconstruction_3( unsigned int neighbors, unsigned int samples)
|
||||
: _generator (0),_mean_neighbors(neighbors), _samples(samples), _squared_radius(-1), _shape(0) {}
|
||||
|
||||
template < class Gt, class FS, class wA, class Ct >
|
||||
Scale_space_surface_reconstruction_3<Gt,FS,wA,Ct>::
|
||||
Scale_space_surface_reconstruction_3( FT sq_radius )
|
||||
: _mean_neighbors(0), _samples(0), _squared_radius(sq_radius),
|
||||
_separate_shells (true), _force_manifold (false), _border_angle (45.), _shape(0) {
|
||||
: _mean_neighbors(0), _samples(0), _squared_radius(sq_radius),_shape(0) {
|
||||
CGAL_precondition( sq_radius >= 0 );
|
||||
}
|
||||
|
||||
|
|
@ -305,7 +301,7 @@ ordered_facet_indices( const Facet& f ) const {
|
|||
template < class Gt, class FS, class wA, class Ct >
|
||||
void
|
||||
Scale_space_surface_reconstruction_3<Gt,FS,wA,Ct>::
|
||||
collect_shell( Cell_handle c, unsigned int li ) {
|
||||
collect_shell( Cell_handle c, unsigned int li, bool separate_shells, bool force_manifold ) {
|
||||
// Collect one surface mesh from the alpha-shape in a fashion similar to ball-pivoting.
|
||||
// Invariant: the facet is regular or singular.
|
||||
|
||||
|
|
@ -336,7 +332,7 @@ collect_shell( Cell_handle c, unsigned int li ) {
|
|||
// Output the facet as a triple of indices.
|
||||
_surface.push_back( ordered_facet_indices(f) );
|
||||
if( !processed ) {
|
||||
if (_separate_shells || _shells.size () == 0)
|
||||
if (separate_shells || _shells.size () == 0)
|
||||
{
|
||||
_shells.push_back( --_surface.end() );
|
||||
_index ++;
|
||||
|
|
@ -349,7 +345,7 @@ collect_shell( Cell_handle c, unsigned int li ) {
|
|||
|
||||
// If the surface is required to be manifold,
|
||||
// the opposite layer should be ignored
|
||||
if (_force_manifold)
|
||||
if (force_manifold)
|
||||
mark_opposite_handled (f);
|
||||
|
||||
// Pivot over each of the facet's edges and continue the surface at the next regular or singular facet.
|
||||
|
|
@ -384,7 +380,7 @@ collect_shell( Cell_handle c, unsigned int li ) {
|
|||
template < class Gt, class FS, class wA, class Ct >
|
||||
void
|
||||
Scale_space_surface_reconstruction_3<Gt,FS,wA,Ct>::
|
||||
collect_facets( ) {
|
||||
collect_facets (bool separate_shells, bool force_manifold) {
|
||||
|
||||
|
||||
// We check each of the facets: if it is not handled and either regular or singular,
|
||||
|
|
@ -394,14 +390,14 @@ collect_facets( ) {
|
|||
case Shape::REGULAR:
|
||||
// Build a surface from the outer cell.
|
||||
if( _shape->classify(fit->first) == Shape::EXTERIOR )
|
||||
collect_shell( *fit );
|
||||
collect_shell( *fit, separate_shells, force_manifold );
|
||||
else
|
||||
collect_shell( _shape->mirror_facet( *fit ) );
|
||||
collect_shell( _shape->mirror_facet( *fit ), separate_shells, force_manifold );
|
||||
break;
|
||||
case Shape::SINGULAR:
|
||||
// Build a surface from both incident cells.
|
||||
collect_shell( *fit );
|
||||
collect_shell( _shape->mirror_facet( *fit ) );
|
||||
collect_shell( *fit, separate_shells, force_manifold );
|
||||
collect_shell( _shape->mirror_facet( *fit ), separate_shells, force_manifold );
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
@ -557,7 +553,7 @@ construct_shape( InputIterator begin, InputIterator end,
|
|||
template < class Gt, class FS, class wA, class Ct >
|
||||
void
|
||||
Scale_space_surface_reconstruction_3<Gt,FS,wA,Ct>::
|
||||
collect_surface( ) {
|
||||
collect_surface (bool separate_shells, bool force_manifold, FT border_angle) {
|
||||
|
||||
clear_surface();
|
||||
if( !has_shape() )
|
||||
|
|
@ -568,7 +564,7 @@ collect_surface( ) {
|
|||
|
||||
// If shells are not separated and no manifold constraint is given,
|
||||
// then the quick collection of facets can be applied
|
||||
if (!_separate_shells && !_force_manifold)
|
||||
if (!separate_shells && !force_manifold)
|
||||
{
|
||||
collect_facets_quick ();
|
||||
_shells.push_back (_surface.begin ());
|
||||
|
|
@ -583,16 +579,16 @@ collect_surface( ) {
|
|||
for( All_cells_iterator cit = _shape->all_cells_begin(); cit != _shape->all_cells_end(); ++cit )
|
||||
cit->info() = 0;
|
||||
|
||||
if (_force_manifold)
|
||||
if (force_manifold)
|
||||
{
|
||||
// If manifold surface is wanted, small volumes (bubbles) are first detected in
|
||||
// order to know which layer to ignore when collecting facets
|
||||
detect_bubbles();
|
||||
detect_bubbles(border_angle);
|
||||
}
|
||||
|
||||
collect_facets ();
|
||||
collect_facets (separate_shells, force_manifold);
|
||||
|
||||
if (_force_manifold)
|
||||
if (force_manifold)
|
||||
{
|
||||
// Even when taking into account facets, some nonmanifold features might remain
|
||||
fix_nonmanifold_edges();
|
||||
|
|
@ -634,7 +630,7 @@ find_two_other_vertices(const Facet& f, Vertex_handle v,
|
|||
template < class Gt, class FS, class wA, class Ct >
|
||||
void
|
||||
Scale_space_surface_reconstruction_3<Gt,FS,wA,Ct>::
|
||||
detect_bubbles() {
|
||||
detect_bubbles(FT border_angle) {
|
||||
|
||||
std::set<Cell_handle> done;
|
||||
|
||||
|
|
@ -723,7 +719,7 @@ detect_bubbles() {
|
|||
c->vertex (i)->point (),
|
||||
c->vertex ((i + (j+2)%3 + 1)%4)->point ());
|
||||
|
||||
if (-_border_angle < angle && angle < _border_angle)
|
||||
if (-border_angle < angle && angle < border_angle)
|
||||
{
|
||||
borders.insert (vedge);
|
||||
}
|
||||
|
|
@ -1125,13 +1121,14 @@ fix_nonmanifold_vertices() {
|
|||
template < class Gt, class FS, class wA, class Ct >
|
||||
void
|
||||
Scale_space_surface_reconstruction_3<Gt,FS,wA,Ct>::
|
||||
reconstruct_surface( unsigned int iterations ) {
|
||||
reconstruct_surface( unsigned int iterations, bool separate_shells,
|
||||
bool force_manifold, FT border_angle) {
|
||||
|
||||
// Smooth the scale space.
|
||||
increase_scale( iterations );
|
||||
|
||||
// Mesh the perturbed points.
|
||||
collect_surface ();
|
||||
collect_surface (separate_shells, force_manifold, border_angle);
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1141,19 +1138,14 @@ template < class InputIterator >
|
|||
void
|
||||
Scale_space_surface_reconstruction_3<Gt,FS,wA,Ct>::
|
||||
reconstruct_surface( InputIterator begin, InputIterator end, unsigned int iterations,
|
||||
bool separate_shells, bool force_manifold,
|
||||
bool separate_shells, bool force_manifold, FT border_angle,
|
||||
typename boost::enable_if< CGAL::is_iterator<InputIterator> >::type*) {
|
||||
|
||||
// Compute the radius for which the mean ball would contain the required number of neighbors.
|
||||
clear();
|
||||
insert( begin, end );
|
||||
|
||||
_separate_shells = separate_shells;
|
||||
_force_manifold = force_manifold;
|
||||
|
||||
reconstruct_surface (iterations);
|
||||
|
||||
|
||||
reconstruct_surface (iterations, separate_shells, force_manifold, border_angle);
|
||||
}
|
||||
/// \endcond
|
||||
|
||||
|
|
|
|||
|
|
@ -226,10 +226,6 @@ private:
|
|||
|
||||
FT _squared_radius; // The squared neighborhood radius.
|
||||
|
||||
bool _separate_shells;
|
||||
bool _force_manifold;
|
||||
FT _border_angle;
|
||||
|
||||
// The shape must be a pointer, because the alpha of a Fixed_alpha_shape_3
|
||||
// can only be set at construction and its assignment operator is private.
|
||||
// We want to be able to set the alpha after constructing the scale-space
|
||||
|
|
@ -268,8 +264,7 @@ public:
|
|||
* \param separate_shells determines whether to collect the surface per shell.
|
||||
* \param force_manifold determines if the surface is forced to be 2-manifold.
|
||||
*/
|
||||
Scale_space_surface_reconstruction_3( unsigned int neighbors, unsigned int samples,
|
||||
bool separate_shells = true, bool force_manifold = false );
|
||||
Scale_space_surface_reconstruction_3( unsigned int neighbors, unsigned int samples);
|
||||
|
||||
/// constructs a surface reconstructor with a given neighborhood radius.
|
||||
/** \param sq_radius is the squared radius of the neighborhood.
|
||||
|
|
@ -300,15 +295,15 @@ private:
|
|||
Triple ordered_facet_indices( const Facet& f ) const;
|
||||
|
||||
// Collect the triangles of one shell of the surface.
|
||||
void collect_shell( Cell_handle c, unsigned int li );
|
||||
void collect_shell( Cell_handle c, unsigned int li, bool separate_shells, bool force_manifold);
|
||||
|
||||
// Collect the triangles of one shell of the surface.
|
||||
void collect_shell( const Facet& f ) {
|
||||
collect_shell( f.first, f.second );
|
||||
void collect_shell( const Facet& f, bool separate_shells, bool force_manifold) {
|
||||
collect_shell( f.first, f.second, separate_shells, force_manifold );
|
||||
}
|
||||
|
||||
// Collect the triangles of the complete surface.
|
||||
void collect_facets( );
|
||||
void collect_facets( bool separate_shells, bool force_manifold );
|
||||
void collect_facets_quick( );
|
||||
|
||||
|
||||
|
|
@ -657,60 +652,6 @@ public:
|
|||
void set_neighborhood_sample_size( unsigned int samples ) { _samples = samples; }
|
||||
/// \}
|
||||
|
||||
/// \name Output Options Parameters
|
||||
/// \{
|
||||
/// determines whether to collect the surface per shell.
|
||||
/** If set to false, the output surface is stored in a single shell.
|
||||
*
|
||||
* \note Setting this parameter to false when 2-manifoldness is
|
||||
* not required allows for a quicker computation of the
|
||||
* reconstruction.
|
||||
*
|
||||
* \sa `shell_begin(std::size_t shell)`
|
||||
* \sa `shell_end(std::size_t shell)`
|
||||
*/
|
||||
void set_separate_shells( bool separate_shells ) { _separate_shells = separate_shells; }
|
||||
|
||||
/// determines if the surface is forced to be 2-manifold.
|
||||
/** If set to true, some facets of the reconstruction are
|
||||
* willingly discarded so that every facet, edge and vertex are
|
||||
* manifold. The discarded facets are accessible by iterating on
|
||||
* the garbage container.
|
||||
*
|
||||
* \note Setting this parameter to false when separate shells are
|
||||
* not required allows for a quicker computation of the
|
||||
* reconstruction.
|
||||
*
|
||||
* \note This function has no effect on an already reconstructed
|
||||
* surface. For the change of requirement (manifold or not) to be
|
||||
* applied, the `reconstruct_surface()` function must be called
|
||||
* again.
|
||||
*
|
||||
* \sa `garbage_begin()`
|
||||
* \sa `garbage_end()`
|
||||
*/
|
||||
void set_force_manifold( bool force_manifold ) { _force_manifold = force_manifold; }
|
||||
|
||||
/// sets the maximal angle between two facets such that the edge
|
||||
/// is seen as a border.
|
||||
/** If the output is forced to be 2-manifold, some almost flat
|
||||
* volume bubbles are detected. To do so, border edges must be
|
||||
* estimated.
|
||||
*
|
||||
* An edge adjacent to 2 regular facets is considered as a border
|
||||
* if it is also adjacent to a singular facet or if the angle
|
||||
* between the two regular facets is lower than this parameter
|
||||
* (set to 45° by default).
|
||||
*
|
||||
* \param border_angle is the maximal angle between two facets
|
||||
* such that their common edge is considered as a border.
|
||||
*
|
||||
* \note This parameter is only used if the output is forced to
|
||||
* be 2-manifold
|
||||
*
|
||||
*/
|
||||
void set_border_angle( FT border_angle) { _border_angle = border_angle; }
|
||||
/// \}
|
||||
|
||||
/// \name Scale-Space Manipulation
|
||||
/// \{
|
||||
|
|
@ -839,12 +780,12 @@ private:
|
|||
|
||||
// collects the surface mesh from the shape.
|
||||
// If the sahep does not yet exist, it is constructed.
|
||||
void collect_surface ( );
|
||||
void collect_surface (bool separate_shells, bool force_manifold, FT border_angle );
|
||||
|
||||
// detects the non-manifold features of the shape
|
||||
void find_two_other_vertices(const Facet& f, Vertex_handle v,
|
||||
Vertex_handle& v1, Vertex_handle& v2);
|
||||
void detect_bubbles();
|
||||
void detect_bubbles( FT border_angle );
|
||||
void fix_nonmanifold_edges();
|
||||
void fix_nonmanifold_vertices();
|
||||
|
||||
|
|
@ -865,16 +806,33 @@ public:
|
|||
* If the neighborhood radius has not been set before, it is automatically
|
||||
* estimated using `estimate_neighborhood_squared_radius()`.
|
||||
*
|
||||
* \param separate_shells determines whether to collect the surface per shell.
|
||||
* \param force_manifold determines if the surface is forced to be 2-manifold.
|
||||
* \param border_angle sets the maximal angle between two facets
|
||||
* such that the edge is seen as a border.
|
||||
*
|
||||
* If the output is forced to be 2-manifold, some almost flat
|
||||
* volume bubbles are detected. To do so, border edges must be
|
||||
* estimated.
|
||||
*
|
||||
* An edge adjacent to 2 regular facets is considered as a border
|
||||
* if it is also adjacent to a singular facet or if the angle
|
||||
* between the two regular facets is lower than this parameter
|
||||
* (set to 45° by default).
|
||||
*
|
||||
* \note This method processes the point set at the current scale. The
|
||||
* points can be set with <code>[insert(begin, end)](\ref insert)</code>.
|
||||
* \note `border_angle` is not used if `force_manifold` is set to false.
|
||||
*
|
||||
* \sa `estimate_neighborhood_squared_radius()`.
|
||||
* \sa `increase_scale(unsigned int iterations)`.
|
||||
*/
|
||||
void reconstruct_surface()
|
||||
{
|
||||
reconstruct_surface(0);
|
||||
}
|
||||
void reconstruct_surface(bool separate_shells = true,
|
||||
bool force_manifold = false,
|
||||
FT border_angle = 45)
|
||||
{
|
||||
reconstruct_surface(0, separate_shells, force_manifold, border_angle);
|
||||
}
|
||||
|
||||
/// gives the number of triangles of the surface.
|
||||
std::size_t number_of_triangles() const { return _surface.size(); }
|
||||
|
|
@ -889,7 +847,8 @@ public:
|
|||
}
|
||||
|
||||
/// \cond internal_doc
|
||||
void reconstruct_surface( unsigned int iterations);
|
||||
void reconstruct_surface( unsigned int iterations, bool separate_shells = true,
|
||||
bool force_manifold = false, FT border_angle = 45);
|
||||
/// \endcond
|
||||
|
||||
/// \cond internal_doc
|
||||
|
|
@ -921,10 +880,10 @@ public:
|
|||
#ifdef DOXYGEN_RUNNING
|
||||
void reconstruct_surface( InputIterator begin, InputIterator end,
|
||||
unsigned int iterations = 0, bool separate_shells = true,
|
||||
bool force_manifold = false);
|
||||
bool force_manifold = false, FT border_angle = 45);
|
||||
#else // DOXYGEN_RUNNING
|
||||
void reconstruct_surface( InputIterator begin, InputIterator end, unsigned int iterations = 0,
|
||||
bool shells = true, bool force_manifold = false,
|
||||
bool separate_shells = true, bool force_manifold = false, FT border_angle = 45,
|
||||
typename boost::enable_if< CGAL::is_iterator<InputIterator> >::type* = NULL );
|
||||
#endif // DOXYGEN_RUNNING
|
||||
/// \endcond
|
||||
|
|
|
|||
Loading…
Reference in New Issue