Commit a5e72d7b authored by Mike Kremer's avatar Mike Kremer

Implemented efficient garbage_collection() function.

git-svn-id: http://www.openvolumemesh.org/svnrepo/OpenVolumeMesh/trunk@198 66977474-1d4b-4f09-8fe9-267525286df2
parent 65d0be26
This diff is collapsed.
......@@ -229,6 +229,8 @@ public:
private:
void mark_higher_dim_entities();
TopologyKernel& kernel_;
VertexPropertyT<OpenVolumeMeshStatus> v_status_;
......
......@@ -79,6 +79,8 @@ public:
protected:
virtual void delete_multiple_entries(const std::vector<bool>& _tags) = 0;
virtual void resize(unsigned int /*_size*/) = 0;
virtual void set_handle(const OpenVolumeMeshHandle& /*_handle*/) = 0;
......
......@@ -99,6 +99,34 @@ public:
return nV;
}
protected:
virtual void delete_multiple_vertices(const std::vector<bool>& _tag) {
assert(_tag.size() == TopologyKernelT::n_vertices());
std::vector<VecT> newVertices;
typename std::vector<VecT>::const_iterator v_it = vertices_.begin();
for(std::vector<bool>::const_iterator t_it = _tag.begin(),
t_end = _tag.end(); t_it != t_end; ++t_it, ++v_it) {
if(!(*t_it)) {
// Not marked as deleted
newVertices.push_back(*v_it);
}
}
// Swap vertices
vertices_.swap(newVertices);
TopologyKernelT::delete_multiple_vertices(_tag);
}
public:
virtual void clear(bool _clearProps = true) {
vertices_.clear();
......
......@@ -47,6 +47,7 @@
#include <limits>
#include <string>
#include <iostream>
#include <vector>
#include "OpenVolumeMeshHandle.hh"
......@@ -63,6 +64,9 @@ namespace OpenVolumeMesh {
class OpenVolumeMeshBaseProperty {
public:
friend class ResourceManager;
template <class PropT, class HandleT> friend class PropertyPtr;
/// Indicates an error when a size is returned by a member.
static const size_t UnknownSize;
......@@ -101,8 +105,6 @@ public:
/// Return a deep copy of self.
virtual OpenVolumeMeshBaseProperty* clone() const = 0;
public:
/// Return the name of the property
const std::string& name() const {
return name_;
......@@ -115,8 +117,6 @@ public:
// Function to deserialize a property
virtual void deserialize(std::istream& /*_istr*/) {}
public:
// I/O support
void set_persistent(bool _persistent) { persistent_ = _persistent; }
......@@ -145,6 +145,11 @@ public:
void set_handle(const OpenVolumeMeshHandle& _handle) { handle_.idx(_handle.idx()); }
protected:
/// Delete multiple entries in list
virtual void delete_multiple_entries(const std::vector<bool>&) = 0;
private:
std::string name_;
......
......@@ -70,6 +70,8 @@ template<class T>
class OpenVolumeMeshPropertyT: public OpenVolumeMeshBaseProperty {
public:
template <class PropT, class HandleT> friend class PropertyPtr;
typedef T Value;
typedef std::vector<T> vector_type;
typedef T value_type;
......@@ -200,6 +202,24 @@ public:
typename vector_type::iterator end() { return data_.end(); }
protected:
/// Delete multiple entries in list
virtual void delete_multiple_entries(const std::vector<bool>& _tags) {
assert(_tags.size() == data_.size());
vector_type new_data;
typename vector_type::iterator d_it = data_.begin();
std::vector<bool>::const_iterator t_it = _tags.begin();
std::vector<bool>::const_iterator t_end = _tags.end();
for(; t_it != t_end; ++t_it, ++d_it) {
if(!*t_it) {
new_data.push_back(*d_it);
}
}
data_.swap(new_data);
}
private:
vector_type data_;
......@@ -215,6 +235,8 @@ template<>
class OpenVolumeMeshPropertyT<bool> : public OpenVolumeMeshBaseProperty {
public:
template <class PropT, class HandleT> friend class PropertyPtr;
typedef std::vector<bool> vector_type;
typedef bool value_type;
typedef vector_type::reference reference;
......@@ -296,6 +318,24 @@ public:
vector_type::iterator end() { return data_.end(); }
protected:
/// Delete multiple entries in list
virtual void delete_multiple_entries(const std::vector<bool>& _tags) {
assert(_tags.size() == data_.size());
vector_type new_data;
typename vector_type::iterator d_it = data_.begin();
std::vector<bool>::const_iterator t_it = _tags.begin();
std::vector<bool>::const_iterator t_end = _tags.end();
for(; t_it != t_end; ++t_it, ++d_it) {
if(!*t_it) {
new_data.push_back(*d_it);
}
}
data_.swap(new_data);
}
private:
vector_type data_;
......@@ -311,6 +351,8 @@ template<>
class OpenVolumeMeshPropertyT<std::string> : public OpenVolumeMeshBaseProperty {
public:
template <class PropT, class HandleT> friend class PropertyPtr;
typedef std::string Value;
typedef std::vector<std::string> vector_type;
typedef std::string value_type;
......@@ -405,6 +447,24 @@ public:
vector_type::iterator end() { return data_.end(); }
protected:
/// Delete multiple entries in list
virtual void delete_multiple_entries(const std::vector<bool>& _tags) {
assert(_tags.size() == data_.size());
vector_type new_data;
typename vector_type::iterator d_it = data_.begin();
std::vector<bool>::const_iterator t_it = _tags.begin();
std::vector<bool>::const_iterator t_end = _tags.end();
for(; t_it != t_end; ++t_it, ++d_it) {
if(!*t_it) {
new_data.push_back(*d_it);
}
}
data_.swap(new_data);
}
private:
vector_type data_;
......
......@@ -106,6 +106,8 @@ public:
protected:
virtual void delete_multiple_entries(const std::vector<bool>& _tags);
virtual void resize(unsigned int _size);
virtual void set_handle(const OpenVolumeMeshHandle& _handle);
......
......@@ -93,4 +93,9 @@ OpenVolumeMeshHandle PropertyPtr<PropT,HandleT>::handle() const {
return ptr::shared_ptr<PropT>::get()->handle();
}
template <class PropT, class HandleT>
void PropertyPtr<PropT,HandleT>::delete_multiple_entries(const std::vector<bool>& _tags) {
ptr::shared_ptr<PropT>::get()->delete_multiple_entries(_tags);
}
} // Namespace OpenVolumeMesh
......@@ -141,4 +141,64 @@ void ResourceManager::release_property(MeshPropHandle _handle) {
remove_property(mesh_props_, _handle.idx());
}
void ResourceManager::delete_multiple_vertex_props(const std::vector<bool>& _tags) {
Properties::iterator vp_it = vertex_props_.begin();
Properties::iterator vp_end = vertex_props_.end();
for(; vp_it != vp_end; ++vp_it) {
(*vp_it)->delete_multiple_entries(_tags);
}
}
void ResourceManager::delete_multiple_edge_props(const std::vector<bool>& _tags) {
Properties::iterator ep_it = edge_props_.begin();
Properties::iterator ep_end = edge_props_.end();
for(; ep_it != ep_end; ++ep_it) {
(*ep_it)->delete_multiple_entries(_tags);
}
// Create tags vector for halfedges
std::vector<bool> hetags;
for(std::vector<bool>::const_iterator t_it = _tags.begin(),
t_end = _tags.end(); t_it != t_end; ++t_it) {
hetags.push_back(*t_it);
hetags.push_back(*t_it);
}
Properties::iterator hep_it = halfedge_props_.begin();
Properties::iterator hep_end = halfedge_props_.end();
for(; hep_it != hep_end; ++hep_it) {
(*hep_it)->delete_multiple_entries(hetags);
}
}
void ResourceManager::delete_multiple_face_props(const std::vector<bool>& _tags) {
Properties::iterator fp_it = face_props_.begin();
Properties::iterator fp_end = face_props_.end();
for(; fp_it != fp_end; ++fp_it) {
(*fp_it)->delete_multiple_entries(_tags);
}
// Create tags vector for halffaces
std::vector<bool> hftags;
for(std::vector<bool>::const_iterator t_it = _tags.begin(),
t_end = _tags.end(); t_it != t_end; ++t_it) {
hftags.push_back(*t_it);
hftags.push_back(*t_it);
}
Properties::iterator hfp_it = halfface_props_.begin();
Properties::iterator hfp_end = halfface_props_.end();
for(; hfp_it != hfp_end; ++hfp_it) {
(*hfp_it)->delete_multiple_entries(hftags);
}
}
void ResourceManager::delete_multiple_cell_props(const std::vector<bool>& _tags) {
Properties::iterator cp_it = cell_props_.begin();
Properties::iterator cp_end = cell_props_.end();
for(; cp_it != cp_end; ++cp_it) {
(*cp_it)->delete_multiple_entries(_tags);
}
}
} // Namespace OpenVolumeMesh
......@@ -218,6 +218,16 @@ public:
Properties::const_iterator mesh_props_end() const { return mesh_props_.end(); }
protected:
void delete_multiple_vertex_props(const std::vector<bool>& _tags);
void delete_multiple_edge_props(const std::vector<bool>& _tags);
void delete_multiple_face_props(const std::vector<bool>& _tags);
void delete_multiple_cell_props(const std::vector<bool>& _tags);
private:
template<class StdVecT>
......
......@@ -895,6 +895,136 @@ CellIter TopologyKernel::delete_cell(const CellHandle& _h) {
//========================================================================================
void TopologyKernel::delete_multiple_vertices(const std::vector<bool>& _tag) {
assert(_tag.size() == n_vertices_);
std::vector<int> newIndices(n_vertices(), -1);
int curIdx = 0;
std::vector<int>::iterator idx_it = newIndices.begin();
for(std::vector<bool>::const_iterator t_it = _tag.begin(),
t_end = _tag.end(); t_it != t_end; ++t_it, ++idx_it) {
if(!(*t_it)) {
// Not marked as deleted
*idx_it = curIdx;
++curIdx;
} else {
--n_vertices_;
}
}
// Delete properties accordingly
delete_multiple_vertex_props(_tag);
EdgeCorrector corrector(newIndices);
std::for_each(edges_.begin(), edges_.end(), corrector);
}
//========================================================================================
void TopologyKernel::delete_multiple_edges(const std::vector<bool>& _tag) {
assert(_tag.size() == n_edges());
std::vector<int> newIndices(n_edges(), -1);
int curIdx = 0;
std::vector<Edge> newEdges;
std::vector<int>::iterator idx_it = newIndices.begin();
std::vector<Edge>::const_iterator e_it = edges_.begin();
for(std::vector<bool>::const_iterator t_it = _tag.begin(),
t_end = _tag.end(); t_it != t_end; ++t_it, ++idx_it, ++e_it) {
if(!(*t_it)) {
// Not marked as deleted
newEdges.push_back(*e_it);
*idx_it = curIdx;
++curIdx;
}
}
// Swap edges
edges_.swap(newEdges);
// Delete properties accordingly
delete_multiple_edge_props(_tag);
FaceCorrector corrector(newIndices);
std::for_each(faces_.begin(), faces_.end(), corrector);
}
//========================================================================================
void TopologyKernel::delete_multiple_faces(const std::vector<bool>& _tag) {
assert(_tag.size() == n_faces());
std::vector<int> newIndices(n_faces(), -1);
int curIdx = 0;
std::vector<Face> newFaces;
std::vector<int>::iterator idx_it = newIndices.begin();
std::vector<Face>::const_iterator f_it = faces_.begin();
for(std::vector<bool>::const_iterator t_it = _tag.begin(),
t_end = _tag.end(); t_it != t_end; ++t_it, ++idx_it, ++f_it) {
if(!(*t_it)) {
// Not marked as deleted
newFaces.push_back(*f_it);
*idx_it = curIdx;
++curIdx;
}
}
// Swap faces
faces_.swap(newFaces);
// Delete properties accordingly
delete_multiple_face_props(_tag);
CellCorrector corrector(newIndices);
std::for_each(cells_.begin(), cells_.end(), corrector);
}
//========================================================================================
void TopologyKernel::delete_multiple_cells(const std::vector<bool>& _tag) {
assert(_tag.size() == n_cells());
std::vector<Cell> newCells;
std::vector<Cell>::const_iterator c_it = cells_.begin();
for(std::vector<bool>::const_iterator t_it = _tag.begin(),
t_end = _tag.end(); t_it != t_end; ++t_it, ++c_it) {
if(!(*t_it)) {
// Not marked as deleted
newCells.push_back(*c_it);
}
}
// Swap cells
cells_.swap(newCells);
// Delete properties accordingly
delete_multiple_cell_props(_tag);
}
//========================================================================================
CellIter TopologyKernel::delete_cell_range(const CellIter& _first, const CellIter& _last) {
assert(_first >= cells_begin());
......
......@@ -76,6 +76,11 @@ public:
typedef OpenVolumeMeshFace Face;
typedef OpenVolumeMeshCell Cell;
// Add StatusAttrib to list of friend classes
// since it provides a garbage collection
// that needs access to some protected methods
friend class StatusAttrib;
//=====================================================================
// Iterators
//=====================================================================
......@@ -339,6 +344,71 @@ public:
virtual CellIter delete_cell(const CellHandle& _h);
protected:
virtual void delete_multiple_vertices(const std::vector<bool>& _tag);
virtual void delete_multiple_edges(const std::vector<bool>& _tag);
virtual void delete_multiple_faces(const std::vector<bool>& _tag);
virtual void delete_multiple_cells(const std::vector<bool>& _tag);
class EdgeCorrector {
public:
EdgeCorrector(const std::vector<int>& _newIndices) :
newIndices_(_newIndices) {}
void operator()(Edge& _edge) {
_edge.set_from_vertex(VertexHandle(newIndices_[_edge.from_vertex().idx()]));
_edge.set_to_vertex(VertexHandle(newIndices_[_edge.to_vertex().idx()]));
}
private:
const std::vector<int>& newIndices_;
};
class FaceCorrector {
public:
FaceCorrector(const std::vector<int>& _newIndices) :
newIndices_(_newIndices) {}
void operator()(Face& _face) {
std::vector<HalfEdgeHandle> hes = _face.halfedges();
for(std::vector<HalfEdgeHandle>::iterator he_it = hes.begin(),
he_end = hes.end(); he_it != he_end; ++he_it) {
EdgeHandle eh = edge_handle(*he_it);
unsigned char opp = (he_it->idx() - halfedge_handle(eh, 0).idx());
*he_it = halfedge_handle(newIndices_[eh.idx()], opp);
}
_face.set_halfedges(hes);
}
private:
const std::vector<int>& newIndices_;
};
class CellCorrector {
public:
CellCorrector(const std::vector<int>& _newIndices) :
newIndices_(_newIndices) {}
void operator()(Cell& _cell) {
std::vector<HalfFaceHandle> hfs = _cell.halffaces();
for(std::vector<HalfFaceHandle>::iterator hf_it = hfs.begin(),
hf_end = hfs.end(); hf_it != hf_end; ++hf_it) {
FaceHandle fh = face_handle(*hf_it);
unsigned char opp = (hf_it->idx() - halfface_handle(fh, 0).idx());
*hf_it = halfface_handle(newIndices_[fh.idx()], opp);
}
_cell.set_halffaces(hfs);
}
private:
const std::vector<int>& newIndices_;
};
public:
/** \brief Delete range of cells
*
* Deletes all cells in range [_first, _last].
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment