Garbage collection with tracking of handles. ( Thanks to Maxime Quiblier for the base of this update)
Unit tests for garbage collection (halfedges still missing yet) uint->unsigned int changes git-svn-id: http://www.openmesh.org/svnrepo/OpenMesh/trunk@640 fdac6126-5c0c-442c-9429-916003d36597
This commit is contained in:
@@ -121,7 +121,7 @@ public:
|
||||
// There are two halfedges stored per edge
|
||||
// Get memory position inside edge vector and devide by size of an edge
|
||||
// to get the corresponding edge for the requested halfedge
|
||||
uint eh = ( (char*)&_he - (char*)&edges_.front() ) / sizeof(Edge) ;
|
||||
unsigned int eh = ( (char*)&_he - (char*)&edges_.front() ) / sizeof(Edge) ;
|
||||
assert((&_he == &edges_[eh].halfedges_[0]) ||
|
||||
(&_he == &edges_[eh].halfedges_[1]));
|
||||
return ((&_he == &edges_[eh].halfedges_[0]) ?
|
||||
@@ -201,19 +201,19 @@ public:
|
||||
|
||||
// --- get i'th items ---
|
||||
|
||||
VertexHandle vertex_handle(uint _i) const
|
||||
VertexHandle vertex_handle(unsigned int _i) const
|
||||
{ return (_i < n_vertices()) ? handle( vertices_[_i] ) : VertexHandle(); }
|
||||
|
||||
HalfedgeHandle halfedge_handle(uint _i) const
|
||||
HalfedgeHandle halfedge_handle(unsigned int _i) const
|
||||
{
|
||||
return (_i < n_halfedges()) ?
|
||||
halfedge_handle(edge_handle(_i/2), _i%2) : HalfedgeHandle();
|
||||
}
|
||||
|
||||
EdgeHandle edge_handle(uint _i) const
|
||||
EdgeHandle edge_handle(unsigned int _i) const
|
||||
{ return (_i < n_edges()) ? handle(edges_[_i]) : EdgeHandle(); }
|
||||
|
||||
FaceHandle face_handle(uint _i) const
|
||||
FaceHandle face_handle(unsigned int _i) const
|
||||
{ return (_i < n_faces()) ? handle(faces_[_i]) : FaceHandle(); }
|
||||
|
||||
public:
|
||||
@@ -257,18 +257,52 @@ public:
|
||||
|
||||
public:
|
||||
// --- resize/reserve ---
|
||||
void resize( uint _n_vertices, uint _n_edges, uint _n_faces );
|
||||
void reserve(uint _n_vertices, uint _n_edges, uint _n_faces );
|
||||
void resize( unsigned int _n_vertices, unsigned int _n_edges, unsigned int _n_faces );
|
||||
void reserve(unsigned int _n_vertices, unsigned int _n_edges, unsigned int _n_faces );
|
||||
|
||||
// --- deletion ---
|
||||
/** \brief garbage collection
|
||||
*
|
||||
* Usually if you delete primitives in OpenMesh, they are only flagged as deleted.
|
||||
* Only when you call garbage collection, they will be actually removed.
|
||||
*
|
||||
*
|
||||
* @param _v Remove deleted vertices?
|
||||
* @param _e Remove deleted edges?
|
||||
* @param _f Remove deleted faces?
|
||||
*/
|
||||
void garbage_collection(bool _v=true, bool _e=true, bool _f=true);
|
||||
|
||||
/** \brief garbage collection
|
||||
*
|
||||
* Usually if you delete primitives in OpenMesh, they are only flagged as deleted.
|
||||
* Only when you call garbage collection, they will be actually removed.
|
||||
*
|
||||
* \note Garbage collection invalidates all handles. If you need to keep track of
|
||||
* a set of handles, you can pass vectors of pointers to the handles to this function
|
||||
*
|
||||
* @param vh_to_update Vertex handles that should get updated
|
||||
* @param hh_to_update Halfedge handles that should get updated
|
||||
* @param fh_to_update Face handles that should get updated
|
||||
* @param _v Remove deleted vertices?
|
||||
* @param _e Remove deleted edges?
|
||||
* @param _f Remove deleted faces?
|
||||
*/
|
||||
template<typename std_API_Container_VHandlePointer,
|
||||
typename std_API_Container_HHandlePointer,
|
||||
typename std_API_Container_FHandlePointer>
|
||||
void garbage_collection(bool _v=true, bool _e=true, bool _f=true,
|
||||
std_API_Container_VHandlePointer* vh_to_update = 0,
|
||||
std_API_Container_HHandlePointer* hh_to_update = 0,
|
||||
std_API_Container_FHandlePointer* fh_to_update = 0);
|
||||
|
||||
void clear();
|
||||
|
||||
// --- number of items ---
|
||||
uint n_vertices() const { return vertices_.size(); }
|
||||
uint n_halfedges() const { return 2*edges_.size(); }
|
||||
uint n_edges() const { return edges_.size(); }
|
||||
uint n_faces() const { return faces_.size(); }
|
||||
unsigned int n_vertices() const { return vertices_.size(); }
|
||||
unsigned int n_halfedges() const { return 2*edges_.size(); }
|
||||
unsigned int n_edges() const { return edges_.size(); }
|
||||
unsigned int n_faces() const { return faces_.size(); }
|
||||
|
||||
bool vertices_empty() const { return vertices_.empty(); }
|
||||
bool halfedges_empty() const { return edges_.empty(); }
|
||||
@@ -292,7 +326,7 @@ public:
|
||||
void set_isolated(VertexHandle _vh)
|
||||
{ vertex(_vh).halfedge_handle_.invalidate(); }
|
||||
|
||||
uint delete_isolated_vertices();
|
||||
unsigned int delete_isolated_vertices();
|
||||
|
||||
// --- halfedge connectivity ---
|
||||
VertexHandle to_vertex_handle(HalfedgeHandle _heh) const
|
||||
@@ -394,7 +428,7 @@ public:
|
||||
{ return next_halfedge_handle(opposite_halfedge_handle(_heh)); }
|
||||
|
||||
// --- edge connectivity ---
|
||||
HalfedgeHandle halfedge_handle(EdgeHandle _eh, uint _i) const
|
||||
HalfedgeHandle halfedge_handle(EdgeHandle _eh, unsigned int _i) const
|
||||
{
|
||||
assert(_i<=1);
|
||||
return HalfedgeHandle((_eh.idx() << 1) + _i);
|
||||
@@ -538,10 +572,10 @@ public:
|
||||
ArrayKernel& kernel_;
|
||||
|
||||
public:
|
||||
const uint bit_mask_;
|
||||
const unsigned int bit_mask_;
|
||||
|
||||
public:
|
||||
StatusSetT(ArrayKernel& _kernel, uint _bit_mask)
|
||||
StatusSetT(ArrayKernel& _kernel, unsigned int _bit_mask)
|
||||
: kernel_(_kernel), bit_mask_(_bit_mask)
|
||||
{}
|
||||
|
||||
@@ -558,14 +592,14 @@ public:
|
||||
{ kernel_.status(_hnd).unset_bit(bit_mask_); }
|
||||
|
||||
/// Note: 0(n) complexity
|
||||
uint size() const
|
||||
unsigned int size() const
|
||||
{
|
||||
uint n_elements = kernel_.status_pph(Handle()).is_valid() ?
|
||||
kernel_.property(kernel_.status_pph(Handle())).n_elements() : 0;
|
||||
uint sz = 0;
|
||||
for (uint i = 0; i < n_elements; ++i)
|
||||
unsigned int n_elements = kernel_.status_pph(Handle()).is_valid() ?
|
||||
kernel_.property(kernel_.status_pph(Handle())).n_elements() : 0;
|
||||
unsigned int sz = 0;
|
||||
for (unsigned int i = 0; i < n_elements; ++i)
|
||||
{
|
||||
sz += (uint)is_in(Handle(i));
|
||||
sz += (unsigned int)is_in(Handle(i));
|
||||
}
|
||||
return sz;
|
||||
}
|
||||
@@ -573,9 +607,9 @@ public:
|
||||
/// Note: O(n) complexity
|
||||
void clear()
|
||||
{
|
||||
uint n_elements = kernel_.status_pph(Handle()).is_valid() ?
|
||||
kernel_.property(kernel_.status_pph(Handle())).n_elements() : 0;
|
||||
for (uint i = 0; i < n_elements; ++i)
|
||||
unsigned int n_elements = kernel_.status_pph(Handle()).is_valid() ?
|
||||
kernel_.property(kernel_.status_pph(Handle())).n_elements() : 0;
|
||||
for (unsigned int i = 0; i < n_elements; ++i)
|
||||
{
|
||||
erase(Handle(i));
|
||||
}
|
||||
@@ -634,7 +668,7 @@ public:
|
||||
typedef typename HandleContainer::const_iterator
|
||||
const_iterator;
|
||||
public:
|
||||
ExtStatusSetT(ArrayKernel& _kernel, uint _capacity_hint = 0)
|
||||
ExtStatusSetT(ArrayKernel& _kernel, unsigned int _capacity_hint = 0)
|
||||
: Base(_kernel)
|
||||
{ handles_.reserve(_capacity_hint); }
|
||||
|
||||
@@ -682,7 +716,7 @@ public:
|
||||
}
|
||||
|
||||
/// Complexity: 0(1)
|
||||
inline uint size() const
|
||||
inline unsigned int size() const
|
||||
{ return handles_.size(); }
|
||||
inline bool empty() const
|
||||
{ return handles_.empty(); }
|
||||
@@ -725,7 +759,7 @@ private:
|
||||
typedef EdgeContainer::const_iterator KernelConstEdgeIter;
|
||||
typedef FaceContainer::iterator KernelFaceIter;
|
||||
typedef FaceContainer::const_iterator KernelConstFaceIter;
|
||||
typedef std::vector<uint> BitMaskContainer;
|
||||
typedef std::vector<unsigned int> BitMaskContainer;
|
||||
|
||||
|
||||
KernelVertexIter vertices_begin() { return vertices_.begin(); }
|
||||
@@ -754,16 +788,16 @@ private:
|
||||
{ return halfedge_bit_masks_; }
|
||||
|
||||
template <class Handle>
|
||||
uint pop_bit_mask(Handle _hnd)
|
||||
unsigned int pop_bit_mask(Handle _hnd)
|
||||
{
|
||||
assert(!bit_masks(_hnd).empty());//check if the client request too many status sets
|
||||
uint bit_mask = bit_masks(_hnd).back();
|
||||
unsigned int bit_mask = bit_masks(_hnd).back();
|
||||
bit_masks(_hnd).pop_back();
|
||||
return bit_mask;
|
||||
}
|
||||
|
||||
template <class Handle>
|
||||
void push_bit_mask(Handle _hnd, uint _bit_mask)
|
||||
void push_bit_mask(Handle _hnd, unsigned int _bit_mask)
|
||||
{
|
||||
assert(std::find(bit_masks(_hnd).begin(), bit_masks(_hnd).end(), _bit_mask) ==
|
||||
bit_masks(_hnd).end());//this mask should be not already used
|
||||
@@ -783,10 +817,10 @@ private:
|
||||
EdgeStatusPropertyHandle edge_status_;
|
||||
FaceStatusPropertyHandle face_status_;
|
||||
|
||||
uint refcount_vstatus_;
|
||||
uint refcount_hstatus_;
|
||||
uint refcount_estatus_;
|
||||
uint refcount_fstatus_;
|
||||
unsigned int refcount_vstatus_;
|
||||
unsigned int refcount_hstatus_;
|
||||
unsigned int refcount_estatus_;
|
||||
unsigned int refcount_fstatus_;
|
||||
|
||||
BitMaskContainer halfedge_bit_masks_;
|
||||
BitMaskContainer edge_bit_masks_;
|
||||
@@ -794,8 +828,14 @@ private:
|
||||
BitMaskContainer face_bit_masks_;
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
#if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_ARRAY_KERNEL_C)
|
||||
# define OPENMESH_ARRAY_KERNEL_TEMPLATES
|
||||
# include "ArrayKernelT.cc"
|
||||
#endif
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_ARRAY_KERNEL_HH defined
|
||||
//=============================================================================
|
||||
|
||||
Reference in New Issue
Block a user