From 6afadfbd4c6f4545c0d5afa2c5c6981d3875b114 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20M=C3=B6bius?= Date: Fri, 23 Oct 2015 08:22:25 +0200 Subject: [PATCH 1/3] Revert "remove dead code" aka Reintroduce status set This reverts commit c5d03587cc7d4bcc25dc1ca09dd9f307d7bcd533. --- src/OpenMesh/Core/Mesh/ArrayKernel.hh | 185 ++++++++++++++++++++++++++ 1 file changed, 185 insertions(+) diff --git a/src/OpenMesh/Core/Mesh/ArrayKernel.hh b/src/OpenMesh/Core/Mesh/ArrayKernel.hh index 9745f744..51397f48 100644 --- a/src/OpenMesh/Core/Mesh/ArrayKernel.hh +++ b/src/OpenMesh/Core/Mesh/ArrayKernel.hh @@ -571,6 +571,191 @@ public: remove_property(face_status_); } + /// --- StatusSet API --- + + template + class StatusSetT + { + protected: + ArrayKernel& kernel_; + + public: + const unsigned int bit_mask_; + + public: + StatusSetT(ArrayKernel& _kernel, 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 + unsigned int size() const + { + 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 += (unsigned int)is_in(Handle(i)); + } + return sz; + } + + /// Note: O(n) complexity + void clear() + { + 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)); + } + } + }; + + friend class StatusSetT; + friend class StatusSetT; + friend class StatusSetT; + friend class StatusSetT; + + /// --- AutoStatusSet API --- + + template + class AutoStatusSetT : public StatusSetT + { + private: + typedef StatusSetT Base; + public: + AutoStatusSetT(ArrayKernel& _kernel) + : StatusSetT(_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; + friend class AutoStatusSetT; + friend class AutoStatusSetT; + friend class AutoStatusSetT; + + typedef AutoStatusSetT VertexStatusSet; + typedef AutoStatusSetT EdgeStatusSet; + typedef AutoStatusSetT FaceStatusSet; + typedef AutoStatusSetT HalfedgeStatusSet; + + /// --- ExtStatusSet API --- (hybrid between a set and an array) + + template + class ExtStatusSetT : public AutoStatusSetT + { + public: + typedef AutoStatusSetT Base; + + protected: + typedef std::vector 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(); } + + //set API + // 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)); + clear(*_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 ExtFaceStatusSet; + typedef ExtStatusSetT ExtVertexStatusSet; + typedef ExtStatusSetT ExtEdgeStatusSet; + typedef ExtStatusSetT ExtHalfedgeStatusSet; + private: // iterators typedef std::vector VertexContainer; From f5d25606562813148639a6faf0742fe6b84fd59d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20M=C3=B6bius?= Date: Fri, 23 Oct 2015 10:25:47 +0200 Subject: [PATCH 2/3] More efficient implementation of opposite_halfedge handle Old code compiled to 0x00000000004594a0 <+0>: lea -0x1(%rsi),%edx 0x00000000004594a3 <+3>: lea 0x1(%rsi),%eax 0x00000000004594a6 <+6>: and $0x1,%esi 0x00000000004594a9 <+9>: cmovne %edx,%eax 0x00000000004594ac <+12>: retq New code creates 0x00000000004594a0 <+0>: mov %esi,%eax 0x00000000004594a2 <+2>: xor $0x1,%eax 0x00000000004594a5 <+5>: retq So no conditionals, jumps and fewer instructions closes #5 --- src/OpenMesh/Core/Mesh/ArrayKernel.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenMesh/Core/Mesh/ArrayKernel.hh b/src/OpenMesh/Core/Mesh/ArrayKernel.hh index 51397f48..b83f3a6d 100644 --- a/src/OpenMesh/Core/Mesh/ArrayKernel.hh +++ b/src/OpenMesh/Core/Mesh/ArrayKernel.hh @@ -425,7 +425,7 @@ public: HalfedgeHandle opposite_halfedge_handle(HalfedgeHandle _heh) const - { return HalfedgeHandle((_heh.idx() & 1) ? _heh.idx()-1 : _heh.idx()+1); } + { return HalfedgeHandle(_heh.idx() ^ 1); } HalfedgeHandle ccw_rotated_halfedge_handle(HalfedgeHandle _heh) const From 6fc135e6924d51db09d20a5a0bc2f2df8a615080 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20M=C3=B6bius?= Date: Fri, 23 Oct 2015 11:54:57 +0200 Subject: [PATCH 3/3] Removed from this branch Revert "Revert "remove dead code" aka Reintroduce status set" This reverts commit 6afadfbd4c6f4545c0d5afa2c5c6981d3875b114. --- src/OpenMesh/Core/Mesh/ArrayKernel.hh | 185 -------------------------- 1 file changed, 185 deletions(-) diff --git a/src/OpenMesh/Core/Mesh/ArrayKernel.hh b/src/OpenMesh/Core/Mesh/ArrayKernel.hh index b83f3a6d..5726252d 100644 --- a/src/OpenMesh/Core/Mesh/ArrayKernel.hh +++ b/src/OpenMesh/Core/Mesh/ArrayKernel.hh @@ -571,191 +571,6 @@ public: remove_property(face_status_); } - /// --- StatusSet API --- - - template - class StatusSetT - { - protected: - ArrayKernel& kernel_; - - public: - const unsigned int bit_mask_; - - public: - StatusSetT(ArrayKernel& _kernel, 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 - unsigned int size() const - { - 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 += (unsigned int)is_in(Handle(i)); - } - return sz; - } - - /// Note: O(n) complexity - void clear() - { - 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)); - } - } - }; - - friend class StatusSetT; - friend class StatusSetT; - friend class StatusSetT; - friend class StatusSetT; - - /// --- AutoStatusSet API --- - - template - class AutoStatusSetT : public StatusSetT - { - private: - typedef StatusSetT Base; - public: - AutoStatusSetT(ArrayKernel& _kernel) - : StatusSetT(_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; - friend class AutoStatusSetT; - friend class AutoStatusSetT; - friend class AutoStatusSetT; - - typedef AutoStatusSetT VertexStatusSet; - typedef AutoStatusSetT EdgeStatusSet; - typedef AutoStatusSetT FaceStatusSet; - typedef AutoStatusSetT HalfedgeStatusSet; - - /// --- ExtStatusSet API --- (hybrid between a set and an array) - - template - class ExtStatusSetT : public AutoStatusSetT - { - public: - typedef AutoStatusSetT Base; - - protected: - typedef std::vector 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(); } - - //set API - // 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)); - clear(*_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 ExtFaceStatusSet; - typedef ExtStatusSetT ExtVertexStatusSet; - typedef ExtStatusSetT ExtEdgeStatusSet; - typedef ExtStatusSetT ExtHalfedgeStatusSet; - private: // iterators typedef std::vector VertexContainer;