Fixed strange mergwe conflict
Merge branch 'ReintroduceStatusSets' Conflicts: src/OpenMesh/Core/Mesh/ArrayKernel.hh
This commit is contained in:
@@ -571,6 +571,199 @@ public:
|
||||
remove_property(face_status_);
|
||||
}
|
||||
|
||||
/// --- StatusSet API ---
|
||||
|
||||
/*!
|
||||
Implements a set of connectivity entities (vertex, edge, face, halfedge)
|
||||
using the available bits in the corresponding mesh status field.
|
||||
|
||||
Status-based sets are much faster than std::set<> and equivalent
|
||||
in performance to std::vector<bool>, but much more convenient.
|
||||
*/
|
||||
template <class HandleT>
|
||||
class StatusSetT
|
||||
{
|
||||
public:
|
||||
typedef HandleT Handle;
|
||||
|
||||
protected:
|
||||
ArrayKernel& kernel_;
|
||||
|
||||
public:
|
||||
const unsigned int bit_mask_;
|
||||
|
||||
public:
|
||||
StatusSetT(ArrayKernel& _kernel, const unsigned int _bit_mask)
|
||||
: kernel_(_kernel), bit_mask_(_bit_mask)
|
||||
{}
|
||||
|
||||
~StatusSetT()
|
||||
{}
|
||||
|
||||
inline bool is_in(Handle _hnd) const
|
||||
{ return kernel_.status(_hnd).is_bit_set(bit_mask_); }
|
||||
|
||||
inline void insert(Handle _hnd)
|
||||
{ kernel_.status(_hnd).set_bit(bit_mask_); }
|
||||
|
||||
inline void erase(Handle _hnd)
|
||||
{ kernel_.status(_hnd).unset_bit(bit_mask_); }
|
||||
|
||||
//! Note: 0(n) complexity
|
||||
size_t size() const
|
||||
{
|
||||
const int n = kernel_.status_pph(Handle()).is_valid() ?
|
||||
(int)kernel_.property(kernel_.status_pph(Handle())).n_elements() : 0;
|
||||
|
||||
size_t sz = 0;
|
||||
for (int i = 0; i < n; ++i)
|
||||
sz += (size_t)is_in(Handle(i));
|
||||
return sz;
|
||||
}
|
||||
|
||||
//! Note: O(n) complexity
|
||||
void clear()
|
||||
{
|
||||
const int n = kernel_.status_pph(Handle()).is_valid() ?
|
||||
(int)kernel_.property(kernel_.status_pph(Handle())).n_elements() : 0;
|
||||
|
||||
for (int i = 0; i < n; ++i)
|
||||
erase(Handle(i));
|
||||
}
|
||||
};
|
||||
|
||||
friend class StatusSetT<VertexHandle>;
|
||||
friend class StatusSetT<EdgeHandle>;
|
||||
friend class StatusSetT<FaceHandle>;
|
||||
friend class StatusSetT<HalfedgeHandle>;
|
||||
|
||||
//! AutoStatusSetT: A status set that automatically picks a status bit
|
||||
template <class HandleT>
|
||||
class AutoStatusSetT : public StatusSetT<HandleT>
|
||||
{
|
||||
private:
|
||||
typedef StatusSetT<Handle> Base;
|
||||
typedef HandleT Handle;
|
||||
|
||||
public:
|
||||
AutoStatusSetT(ArrayKernel& _kernel)
|
||||
: StatusSetT<Handle>(_kernel, _kernel.pop_bit_mask(Handle()))
|
||||
{ /*assert(size() == 0);*/ } //the set should be empty on creation
|
||||
|
||||
~AutoStatusSetT()
|
||||
{
|
||||
//assert(size() == 0);//the set should be empty on leave?
|
||||
Base::kernel_.push_bit_mask(Handle(), Base::bit_mask_);
|
||||
}
|
||||
};
|
||||
|
||||
friend class AutoStatusSetT<VertexHandle>;
|
||||
friend class AutoStatusSetT<EdgeHandle>;
|
||||
friend class AutoStatusSetT<FaceHandle>;
|
||||
friend class AutoStatusSetT<HalfedgeHandle>;
|
||||
|
||||
typedef AutoStatusSetT<VertexHandle> VertexStatusSet;
|
||||
typedef AutoStatusSetT<EdgeHandle> EdgeStatusSet;
|
||||
typedef AutoStatusSetT<FaceHandle> FaceStatusSet;
|
||||
typedef AutoStatusSetT<HalfedgeHandle> HalfedgeStatusSet;
|
||||
|
||||
//! ExtStatusSet: A status set augmented with an array
|
||||
template <class HandleT>
|
||||
class ExtStatusSetT : public AutoStatusSetT<HandleT>
|
||||
{
|
||||
public:
|
||||
typedef HandleT Handle;
|
||||
typedef AutoStatusSetT<Handle> Base;
|
||||
|
||||
protected:
|
||||
typedef std::vector<Handle> HandleContainer;
|
||||
HandleContainer handles_;
|
||||
|
||||
public:
|
||||
typedef typename HandleContainer::iterator
|
||||
iterator;
|
||||
typedef typename HandleContainer::const_iterator
|
||||
const_iterator;
|
||||
public:
|
||||
ExtStatusSetT(ArrayKernel& _kernel, size_t _capacity_hint = 0)
|
||||
: Base(_kernel)
|
||||
{ handles_.reserve(_capacity_hint); }
|
||||
|
||||
~ExtStatusSetT()
|
||||
{ clear(); }
|
||||
|
||||
// Complexity: O(1)
|
||||
inline void insert(Handle _hnd)
|
||||
{
|
||||
if (!is_in(_hnd))
|
||||
{
|
||||
Base::insert(_hnd);
|
||||
handles_.push_back(_hnd);
|
||||
}
|
||||
}
|
||||
|
||||
//! Complexity: O(k), (k - number of the elements in the set)
|
||||
inline void erase(Handle _hnd)
|
||||
{
|
||||
if (is_in(_hnd))
|
||||
{
|
||||
iterator it = std::find(begin(), end(), _hnd);
|
||||
erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
//! Complexity: O(1)
|
||||
inline void erase(iterator _it)
|
||||
{
|
||||
assert(_it != end() && is_in(*_it));
|
||||
Base::erase(*_it);
|
||||
*_it = handles_.back();
|
||||
_it.pop_back();
|
||||
}
|
||||
|
||||
inline void clear()
|
||||
{
|
||||
for (iterator it = begin(); it != end(); ++it)
|
||||
{
|
||||
assert(is_in(*it));
|
||||
Base::erase(*it);
|
||||
}
|
||||
handles_.clear();
|
||||
}
|
||||
|
||||
/// Complexity: 0(1)
|
||||
inline unsigned int size() const
|
||||
{ return handles_.size(); }
|
||||
inline bool empty() const
|
||||
{ return handles_.empty(); }
|
||||
|
||||
//Vector API
|
||||
inline iterator begin()
|
||||
{ return handles_.begin(); }
|
||||
inline const_iterator begin() const
|
||||
{ return handles_.begin(); }
|
||||
|
||||
inline iterator end()
|
||||
{ return handles_.end(); }
|
||||
inline const_iterator end() const
|
||||
{ return handles_.end(); }
|
||||
|
||||
inline Handle& front()
|
||||
{ return handles_.front(); }
|
||||
inline const Handle& front() const
|
||||
{ return handles_.front(); }
|
||||
|
||||
inline Handle& back()
|
||||
{ return handles_.back(); }
|
||||
inline const Handle& back() const
|
||||
{ return handles_.back(); }
|
||||
};
|
||||
|
||||
typedef ExtStatusSetT<FaceHandle> ExtFaceStatusSet;
|
||||
typedef ExtStatusSetT<VertexHandle> ExtVertexStatusSet;
|
||||
typedef ExtStatusSetT<EdgeHandle> ExtEdgeStatusSet;
|
||||
typedef ExtStatusSetT<HalfedgeHandle> ExtHalfedgeStatusSet;
|
||||
|
||||
private:
|
||||
// iterators
|
||||
typedef std::vector<Vertex> VertexContainer;
|
||||
|
||||
Reference in New Issue
Block a user