Merge branch 'Decimater_selection' into 'master'
Decimater selection See merge request OpenMesh/OpenMesh!272
This commit is contained in:
@@ -100,26 +100,28 @@ public:
|
||||
* @brief Perform a number of collapses on the mesh.
|
||||
* @param _n_collapses Desired number of collapses. If zero (default), attempt
|
||||
* to do as many collapses as possible.
|
||||
* @param _only_selected Only consider vertices which are selected for decimation
|
||||
* @return Number of collapses that were actually performed.
|
||||
* @note This operation only marks the removed mesh elements for deletion. In
|
||||
* order to actually remove the decimated elements from the mesh, a
|
||||
* subsequent call to ArrayKernel::garbage_collection() is required.
|
||||
*/
|
||||
size_t decimate( size_t _n_collapses = 0 );
|
||||
size_t decimate( size_t _n_collapses = 0 , bool _only_selected = false);
|
||||
|
||||
/**
|
||||
* @brief Decimate the mesh to a desired target vertex complexity.
|
||||
* @param _n_vertices Target complexity, i.e. desired number of remaining
|
||||
* vertices after decimation.
|
||||
* @param _only_selected Only consider vertices which are selected for decimation
|
||||
* @return Number of collapses that were actually performed.
|
||||
* @note This operation only marks the removed mesh elements for deletion. In
|
||||
* order to actually remove the decimated elements from the mesh, a
|
||||
* subsequent call to ArrayKernel::garbage_collection() is required.
|
||||
*/
|
||||
size_t decimate_to( size_t _n_vertices )
|
||||
size_t decimate_to( size_t _n_vertices , bool _only_selected = false)
|
||||
{
|
||||
return ( (_n_vertices < this->mesh().n_vertices()) ?
|
||||
decimate( this->mesh().n_vertices() - _n_vertices ) : 0 );
|
||||
decimate( this->mesh().n_vertices() - _n_vertices , _only_selected ) : 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -127,6 +129,7 @@ public:
|
||||
* complexity is achieved.
|
||||
* @param _n_vertices Target vertex complexity.
|
||||
* @param _n_faces Target face complexity.
|
||||
* @param _only_selected Only consider vertices which are selected for decimation
|
||||
* @return Number of collapses that were actually performed.
|
||||
* @note Decimation stops as soon as either one of the two complexity bounds
|
||||
* is satisfied.
|
||||
@@ -134,7 +137,7 @@ public:
|
||||
* order to actually remove the decimated elements from the mesh, a
|
||||
* subsequent call to ArrayKernel::garbage_collection() is required.
|
||||
*/
|
||||
size_t decimate_to_faces( size_t _n_vertices=0, size_t _n_faces=0 );
|
||||
size_t decimate_to_faces( size_t _n_vertices=0, size_t _n_faces=0 , bool _only_selected = false);
|
||||
|
||||
public:
|
||||
|
||||
|
||||
@@ -147,12 +147,11 @@ void DecimaterT<Mesh>::heap_vertex(VertexHandle _vh) {
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template<class Mesh>
|
||||
size_t DecimaterT<Mesh>::decimate(size_t _n_collapses) {
|
||||
size_t DecimaterT<Mesh>::decimate(size_t _n_collapses, bool _only_selected) {
|
||||
|
||||
if (!this->is_initialized())
|
||||
return 0;
|
||||
|
||||
typename Mesh::VertexIter v_it, v_end(mesh_.vertices_end());
|
||||
typename Mesh::VertexHandle vp;
|
||||
typename Mesh::HalfedgeHandle v0v1;
|
||||
typename Mesh::VertexVertexIter vv_it;
|
||||
@@ -181,10 +180,15 @@ size_t DecimaterT<Mesh>::decimate(size_t _n_collapses) {
|
||||
|
||||
heap_->reserve(mesh_.n_vertices());
|
||||
|
||||
for (v_it = mesh_.vertices_begin(); v_it != v_end; ++v_it) {
|
||||
heap_->reset_heap_position(*v_it);
|
||||
if (!mesh_.status(*v_it).deleted())
|
||||
heap_vertex(*v_it);
|
||||
for ( auto v_it : mesh_.vertices() ) {
|
||||
heap_->reset_heap_position(v_it);
|
||||
|
||||
if (!mesh_.status(v_it).deleted()) {
|
||||
if (!_only_selected || mesh_.status(v_it).selected() ) {
|
||||
heap_vertex(v_it);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const bool update_normals = mesh_.has_face_normals();
|
||||
@@ -231,6 +235,7 @@ size_t DecimaterT<Mesh>::decimate(size_t _n_collapses) {
|
||||
// update heap (former one ring of decimated vertex)
|
||||
for (s_it = support.begin(), s_end = support.end(); s_it != s_end; ++s_it) {
|
||||
assert(!mesh_.status(*s_it).deleted());
|
||||
if (!_only_selected || mesh_.status(*s_it).selected() )
|
||||
heap_vertex(*s_it);
|
||||
}
|
||||
|
||||
@@ -251,7 +256,7 @@ size_t DecimaterT<Mesh>::decimate(size_t _n_collapses) {
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template<class Mesh>
|
||||
size_t DecimaterT<Mesh>::decimate_to_faces(size_t _nv, size_t _nf) {
|
||||
size_t DecimaterT<Mesh>::decimate_to_faces(size_t _nv, size_t _nf, bool _only_selected) {
|
||||
|
||||
if (!this->is_initialized())
|
||||
return 0;
|
||||
@@ -259,7 +264,6 @@ size_t DecimaterT<Mesh>::decimate_to_faces(size_t _nv, size_t _nf) {
|
||||
if (_nv >= mesh_.n_vertices() || _nf >= mesh_.n_faces())
|
||||
return 0;
|
||||
|
||||
typename Mesh::VertexIter v_it, v_end(mesh_.vertices_end());
|
||||
typename Mesh::VertexHandle vp;
|
||||
typename Mesh::HalfedgeHandle v0v1;
|
||||
typename Mesh::VertexVertexIter vv_it;
|
||||
@@ -283,10 +287,13 @@ size_t DecimaterT<Mesh>::decimate_to_faces(size_t _nv, size_t _nf) {
|
||||
#endif
|
||||
heap_->reserve(mesh_.n_vertices());
|
||||
|
||||
for (v_it = mesh_.vertices_begin(); v_it != v_end; ++v_it) {
|
||||
heap_->reset_heap_position(*v_it);
|
||||
if (!mesh_.status(*v_it).deleted())
|
||||
heap_vertex(*v_it);
|
||||
for ( auto v_it : mesh_.vertices() ) {
|
||||
heap_->reset_heap_position(v_it);
|
||||
if (!mesh_.status(v_it).deleted()) {
|
||||
if (!_only_selected || mesh_.status(v_it).selected() ) {
|
||||
heap_vertex(v_it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const bool update_normals = mesh_.has_face_normals();
|
||||
@@ -340,6 +347,7 @@ size_t DecimaterT<Mesh>::decimate_to_faces(size_t _nv, size_t _nf) {
|
||||
// update heap (former one ring of decimated vertex)
|
||||
for (s_it = support.begin(), s_end = support.end(); s_it != s_end; ++s_it) {
|
||||
assert(!mesh_.status(*s_it).deleted());
|
||||
if (!_only_selected || mesh_.status(*s_it).selected() )
|
||||
heap_vertex(*s_it);
|
||||
}
|
||||
|
||||
|
||||
@@ -95,29 +95,56 @@ public: //------------------------------------------------------ public methods
|
||||
|
||||
public:
|
||||
|
||||
/** Decimate (perform _n_collapses collapses). Return number of
|
||||
performed collapses. If _n_collapses is not given reduce as
|
||||
much as possible */
|
||||
size_t decimate( size_t _n_collapses );
|
||||
/**
|
||||
* @brief Decimate (perform _n_collapses collapses). Return number of
|
||||
* performed collapses. If _n_collapses is not given reduce as
|
||||
* much as possible
|
||||
* @param _n_collapses Desired number of collapses. If zero (default), attempt
|
||||
* to do as many collapses as possible.
|
||||
* @param _only_selected Only consider vertices which are selected for decimation
|
||||
* @return Number of collapses that were actually performed.
|
||||
* @note This operation only marks the removed mesh elements for deletion. In
|
||||
* order to actually remove the decimated elements from the mesh, a
|
||||
* subsequent call to ArrayKernel::garbage_collection() is required.
|
||||
*/
|
||||
size_t decimate( size_t _n_collapses , bool _only_selected = false);
|
||||
|
||||
/// Decimate to target complexity, returns number of collapses
|
||||
size_t decimate_to( size_t _n_vertices )
|
||||
/**
|
||||
* @brief Decimate the mesh to a desired target vertex complexity.
|
||||
* @param _n_vertices Target complexity, i.e. desired number of remaining
|
||||
* vertices after decimation.
|
||||
* @param _only_selected Only consider vertices which are selected for decimation
|
||||
* @return Number of collapses that were actually performed.
|
||||
* @note This operation only marks the removed mesh elements for deletion. In
|
||||
* order to actually remove the decimated elements from the mesh, a
|
||||
* subsequent call to ArrayKernel::garbage_collection() is required.
|
||||
*/
|
||||
size_t decimate_to( size_t _n_vertices , bool _only_selected = false)
|
||||
{
|
||||
return ( (_n_vertices < this->mesh().n_vertices()) ?
|
||||
decimate( this->mesh().n_vertices() - _n_vertices ) : 0 );
|
||||
decimate( this->mesh().n_vertices() - _n_vertices , _only_selected ) : 0 );
|
||||
}
|
||||
|
||||
/** Decimate to target complexity (vertices and faces).
|
||||
* Stops when the number of vertices or the number of faces is reached.
|
||||
* Returns number of performed collapses.
|
||||
/**
|
||||
* @brief Attempts to decimate the mesh until a desired vertex or face
|
||||
* complexity is achieved.
|
||||
* @param _n_vertices Target vertex complexity.
|
||||
* @param _n_faces Target face complexity.
|
||||
* @param _only_selected Only consider vertices which are selected for decimation
|
||||
* @return Number of collapses that were actually performed.
|
||||
* @note Decimation stops as soon as either one of the two complexity bounds
|
||||
* is satisfied.
|
||||
* @note This operation only marks the removed mesh elements for deletion. In
|
||||
* order to actually remove the decimated elements from the mesh, a
|
||||
* subsequent call to ArrayKernel::garbage_collection() is required.
|
||||
*/
|
||||
size_t decimate_to_faces( size_t _n_vertices=0, size_t _n_faces=0 );
|
||||
size_t decimate_to_faces( size_t _n_vertices=0, size_t _n_faces=0 , bool _only_selected = false);
|
||||
|
||||
/**
|
||||
* Decimate only with constraints, while _factor gives the
|
||||
* percentage of the constraints that should be used
|
||||
*/
|
||||
size_t decimate_constraints_only(float _factor);
|
||||
size_t decimate_constraints_only(float _factor, bool _only_selected = false);
|
||||
|
||||
size_t samples(){return randomSamples_;}
|
||||
void set_samples(const size_t _value){randomSamples_ = _value;}
|
||||
|
||||
@@ -99,7 +99,7 @@ McDecimaterT<Mesh>::~McDecimaterT() {
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template<class Mesh>
|
||||
size_t McDecimaterT<Mesh>::decimate(size_t _n_collapses) {
|
||||
size_t McDecimaterT<Mesh>::decimate(size_t _n_collapses, bool _only_selected) {
|
||||
|
||||
if (!this->is_initialized())
|
||||
return 0;
|
||||
@@ -142,8 +142,8 @@ size_t McDecimaterT<Mesh>::decimate(size_t _n_collapses) {
|
||||
tmpHandle = typename Mesh::HalfedgeHandle( (double(rand()) / double(RAND_MAX) ) * double(mesh_.n_halfedges()-1) );
|
||||
#endif
|
||||
|
||||
// if it is not deleted, we analyse it
|
||||
if ( ! mesh_.status(tmpHandle).deleted() ) {
|
||||
// if it is not deleted, we analyze it
|
||||
if ( ! mesh_.status(tmpHandle).deleted() && (!_only_selected || mesh_.status(tmpHandle).selected() ) ) {
|
||||
|
||||
CollapseInfo ci(mesh_, tmpHandle);
|
||||
|
||||
@@ -223,7 +223,7 @@ size_t McDecimaterT<Mesh>::decimate(size_t _n_collapses) {
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template<class Mesh>
|
||||
size_t McDecimaterT<Mesh>::decimate_to_faces(size_t _nv, size_t _nf) {
|
||||
size_t McDecimaterT<Mesh>::decimate_to_faces(size_t _nv, size_t _nf, bool _only_selected) {
|
||||
|
||||
if (!this->is_initialized())
|
||||
return 0;
|
||||
@@ -273,8 +273,8 @@ size_t McDecimaterT<Mesh>::decimate_to_faces(size_t _nv, size_t _nf) {
|
||||
tmpHandle = typename Mesh::HalfedgeHandle( ( double(rand()) / double(RAND_MAX) ) * double(mesh_.n_halfedges() - 1));
|
||||
#endif
|
||||
|
||||
// if it is not deleted, we analyse it
|
||||
if (!mesh_.status(tmpHandle).deleted()) {
|
||||
// if it is not deleted, we analyze it
|
||||
if ( ! mesh_.status(tmpHandle).deleted() && (!_only_selected || mesh_.status(tmpHandle).selected() ) ) {
|
||||
|
||||
CollapseInfo ci(mesh_, tmpHandle);
|
||||
|
||||
@@ -366,7 +366,7 @@ size_t McDecimaterT<Mesh>::decimate_to_faces(size_t _nv, size_t _nf) {
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template<class Mesh>
|
||||
size_t McDecimaterT<Mesh>::decimate_constraints_only(float _factor) {
|
||||
size_t McDecimaterT<Mesh>::decimate_constraints_only(float _factor, bool _only_selected) {
|
||||
|
||||
if (!this->is_initialized())
|
||||
return 0;
|
||||
@@ -419,7 +419,8 @@ size_t McDecimaterT<Mesh>::decimate_constraints_only(float _factor) {
|
||||
#endif
|
||||
|
||||
// if it is not deleted, we analyze it
|
||||
if (!mesh_.status(mesh_.edge_handle(tmpHandle)).deleted()) {
|
||||
if (!mesh_.status(mesh_.edge_handle(tmpHandle)).deleted() &&
|
||||
(!_only_selected || ( mesh_.status(mesh_.to_vertex_handle(tmpHandle)).selected() && mesh_.status(mesh_.from_vertex_handle(tmpHandle)).selected() ) ) ) {
|
||||
|
||||
CollapseInfo ci(mesh_, tmpHandle);
|
||||
|
||||
|
||||
@@ -95,23 +95,61 @@ public: //------------------------------------------------------ public methods
|
||||
|
||||
public:
|
||||
|
||||
/** Decimate (perform _n_collapses collapses). Return number of
|
||||
performed collapses. If _n_collapses is not given reduce as
|
||||
much as possible */
|
||||
size_t decimate( const size_t _n_collapses, const float _mc_factor );
|
||||
/**
|
||||
* @brief Decimate (perform _n_collapses collapses). Return number of
|
||||
* performed collapses. If _n_collapses is not given reduce as
|
||||
* much as possible
|
||||
* @param _n_collapses Desired number of collapses. If zero (default), attempt
|
||||
* to do as many collapses as possible.
|
||||
* @param _mc_factor Number between 0 and one defining how much percent of the
|
||||
* collapses should be performed by MC Decimater before switching to
|
||||
* Fixed decimation
|
||||
* @param _only_selected Only consider vertices which are selected for decimation
|
||||
* @return Number of collapses that were actually performed.
|
||||
* @note This operation only marks the removed mesh elements for deletion. In
|
||||
* order to actually remove the decimated elements from the mesh, a
|
||||
* subsequent call to ArrayKernel::garbage_collection() is required.
|
||||
*/
|
||||
size_t decimate( const size_t _n_collapses, const float _mc_factor , bool _only_selected = false);
|
||||
|
||||
/// Decimate to target complexity, returns number of collapses
|
||||
size_t decimate_to( size_t _n_vertices, const float _mc_factor )
|
||||
/**
|
||||
* @brief Decimate the mesh to a desired target vertex complexity.
|
||||
* @param _n_vertices Target complexity, i.e. desired number of remaining
|
||||
* vertices after decimation.
|
||||
|
||||
* @param _only_selected Only consider vertices which are selected for decimation
|
||||
* @param _mc_factor Number between 0 and one defining how much percent of the
|
||||
* collapses should be performed by MC Decimater before switching to
|
||||
* Fixed decimation
|
||||
* @return Number of collapses that were actually performed.
|
||||
* @note This operation only marks the removed mesh elements for deletion. In
|
||||
* order to actually remove the decimated elements from the mesh, a
|
||||
* subsequent call to ArrayKernel::garbage_collection() is required.
|
||||
*/
|
||||
size_t decimate_to( size_t _n_vertices, const float _mc_factor , bool _only_selected = false)
|
||||
{
|
||||
return ( (_n_vertices < this->mesh().n_vertices()) ?
|
||||
decimate( this->mesh().n_vertices() - _n_vertices, _mc_factor ) : 0 );
|
||||
decimate( this->mesh().n_vertices() - _n_vertices, _mc_factor , _only_selected) : 0 );
|
||||
}
|
||||
|
||||
/** Decimate to target complexity (vertices and faces).
|
||||
* Stops when the number of vertices or the number of faces is reached.
|
||||
* Returns number of performed collapses.
|
||||
/**
|
||||
* @brief Attempts to decimate the mesh until a desired vertex or face
|
||||
* complexity is achieved.
|
||||
* @param _n_vertices Target vertex complexity.
|
||||
* @param _n_faces Target face complexity.
|
||||
* @param _mc_factor Number between 0 and one defining how much percent of the
|
||||
* collapses should be performed by MC Decimater before switching to
|
||||
* Fixed decimation
|
||||
* @param _only_selected Only consider vertices which are selected for decimation
|
||||
* @return Number of collapses that were actually performed.
|
||||
* @note Decimation stops as soon as either one of the two complexity bounds
|
||||
* is satisfied.
|
||||
* @note This operation only marks the removed mesh elements for deletion. In
|
||||
* order to actually remove the decimated elements from the mesh, a
|
||||
* subsequent call to ArrayKernel::garbage_collection() is required.
|
||||
*/
|
||||
size_t decimate_to_faces( const size_t _n_vertices=0, const size_t _n_faces=0 , const float _mc_factor = 0.8);
|
||||
|
||||
size_t decimate_to_faces( const size_t _n_vertices=0, const size_t _n_faces=0 , const float _mc_factor = 0.8 , bool _only_selected = false);
|
||||
|
||||
private: //------------------------------------------------------- private data
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ MixedDecimaterT<Mesh>::~MixedDecimaterT() {
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template<class Mesh>
|
||||
size_t MixedDecimaterT<Mesh>::decimate(const size_t _n_collapses, const float _mc_factor) {
|
||||
size_t MixedDecimaterT<Mesh>::decimate(const size_t _n_collapses, const float _mc_factor, bool _only_selected) {
|
||||
|
||||
if (_mc_factor > 1.0)
|
||||
return 0;
|
||||
@@ -92,21 +92,21 @@ size_t MixedDecimaterT<Mesh>::decimate(const size_t _n_collapses, const float _m
|
||||
|
||||
size_t r_collapses = 0;
|
||||
if (_mc_factor > 0.0)
|
||||
r_collapses = McDecimaterT<Mesh>::decimate(n_collapses_mc);
|
||||
r_collapses = McDecimaterT<Mesh>::decimate(n_collapses_mc,_only_selected);
|
||||
|
||||
// returns, if the previous steps were aborted by the observer
|
||||
if (this->observer() && this->observer()->abort())
|
||||
return r_collapses;
|
||||
|
||||
if (_mc_factor < 1.0)
|
||||
r_collapses += DecimaterT<Mesh>::decimate(n_collapses_inc);
|
||||
r_collapses += DecimaterT<Mesh>::decimate(n_collapses_inc,_only_selected);
|
||||
|
||||
return r_collapses;
|
||||
|
||||
}
|
||||
|
||||
template<class Mesh>
|
||||
size_t MixedDecimaterT<Mesh>::decimate_to_faces(const size_t _n_vertices,const size_t _n_faces, const float _mc_factor ){
|
||||
size_t MixedDecimaterT<Mesh>::decimate_to_faces(const size_t _n_vertices,const size_t _n_faces, const float _mc_factor , bool _only_selected){
|
||||
|
||||
if (_mc_factor > 1.0)
|
||||
return 0;
|
||||
@@ -122,7 +122,7 @@ size_t MixedDecimaterT<Mesh>::decimate_to_faces(const size_t _n_vertices,const
|
||||
size_t n_vertices_mc = static_cast<size_t>(mesh_vertices - _mc_factor * (mesh_vertices - _n_vertices));
|
||||
size_t n_faces_mc = static_cast<size_t>(mesh_faces - _mc_factor * (mesh_faces - _n_faces));
|
||||
|
||||
r_collapses = McDecimaterT<Mesh>::decimate_to_faces(n_vertices_mc, n_faces_mc);
|
||||
r_collapses = McDecimaterT<Mesh>::decimate_to_faces(n_vertices_mc, n_faces_mc,_only_selected);
|
||||
} else {
|
||||
|
||||
const size_t samples = this->samples();
|
||||
@@ -145,7 +145,7 @@ size_t MixedDecimaterT<Mesh>::decimate_to_faces(const size_t _n_vertices,const
|
||||
float decimaterLevel = (float(i + 1)) * _mc_factor / (float(steps) );
|
||||
|
||||
this->set_samples(samples);
|
||||
r_collapses += McDecimaterT<Mesh>::decimate_constraints_only(decimaterLevel);
|
||||
r_collapses += McDecimaterT<Mesh>::decimate_constraints_only(decimaterLevel,_only_selected);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -159,7 +159,7 @@ size_t MixedDecimaterT<Mesh>::decimate_to_faces(const size_t _n_vertices,const
|
||||
|
||||
//reduce the rest of the mesh
|
||||
if (_mc_factor < 1.0) {
|
||||
r_collapses += DecimaterT<Mesh>::decimate_to_faces(_n_vertices,_n_faces);
|
||||
r_collapses += DecimaterT<Mesh>::decimate_to_faces(_n_vertices,_n_faces,_only_selected);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user