Developer Documentation
OpenVolumeMeshHandle.hh
1 /*===========================================================================*\
2  * *
3  * OpenVolumeMesh *
4  * Copyright (C) 2011 by Computer Graphics Group, RWTH Aachen *
5  * www.openvolumemesh.org *
6  * *
7  *---------------------------------------------------------------------------*
8  * This file is part of OpenVolumeMesh. *
9  * *
10  * OpenVolumeMesh is free software: you can redistribute it and/or modify *
11  * it under the terms of the GNU Lesser General Public License as *
12  * published by the Free Software Foundation, either version 3 of *
13  * the License, or (at your option) any later version with the *
14  * following exceptions: *
15  * *
16  * If other files instantiate templates or use macros *
17  * or inline functions from this file, or you compile this file and *
18  * link it with other files to produce an executable, this file does *
19  * not by itself cause the resulting executable to be covered by the *
20  * GNU Lesser General Public License. This exception does not however *
21  * invalidate any other reasons why the executable file might be *
22  * covered by the GNU Lesser General Public License. *
23  * *
24  * OpenVolumeMesh is distributed in the hope that it will be useful, *
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
27  * GNU Lesser General Public License for more details. *
28  * *
29  * You should have received a copy of the GNU LesserGeneral Public *
30  * License along with OpenVolumeMesh. If not, *
31  * see <http://www.gnu.org/licenses/>. *
32  * *
33 \*===========================================================================*/
34 
35 #pragma once
36 
37 #include <algorithm>
38 #include <iosfwd>
39 #include <vector>
40 #include <cassert>
41 #include <limits>
42 
43 #include "Entities.hh"
44 #include "../System/FunctionalInclude.hh"
45 #include "../System/Deprecation.hh"
46 #include "OpenVolumeMesh/Config/Export.hh"
47 
48 namespace OpenVolumeMesh {
49 
50 // Define handle types in order to distinguish different entities by their indices
51 class OVM_EXPORT OpenVolumeMeshHandle {
52 public:
53  // Default constructor
54  explicit constexpr OpenVolumeMeshHandle(int _idx) : idx_(_idx) {}
55 
56  OpenVolumeMeshHandle& operator=(int _idx) {
57  idx_ = _idx;
58  return *this;
59  }
60 
61  OpenVolumeMeshHandle(const OpenVolumeMeshHandle& _idx) = default;
62  OpenVolumeMeshHandle& operator=(const OpenVolumeMeshHandle& _idx) = default;
63 
64  inline bool is_valid() const { return idx_ != -1; }
65 
66  inline bool operator<(const OpenVolumeMeshHandle& _idx) const { return (this->idx_ < _idx.idx_); }
67 
68  inline bool operator<(int _idx) const { return idx_ < _idx; }
69 
70  inline bool operator>(const OpenVolumeMeshHandle& _idx) const { return (this->idx_ > _idx.idx_); }
71 
72  inline bool operator>(int _idx) const { return idx_ > _idx; }
73 
74  inline bool operator==(const OpenVolumeMeshHandle& _h) const { return _h.idx_ == this->idx_; }
75 
76  inline bool operator!=(const OpenVolumeMeshHandle& _h) const { return _h.idx_ != this->idx_; }
77 
78  inline const int& idx() const { return idx_; }
79 
81  inline size_t uidx() const { assert(is_valid()); return static_cast<size_t>(idx_); }
82 
83  void idx(const int& _idx) { idx_ = _idx; }
84 
85 #if OVM_ENABLE_DEPRECATED_APIS
86  OVM_DEPRECATED("use explicit .idx() instead")
87  inline operator int() const { return idx_; }
88 #endif
89 
90  void reset() { idx_ = -1; }
91 
92 private:
93  int idx_;
94 };
95 
96 template<typename EntityTag,
97  typename = typename std::enable_if<is_entity<EntityTag>::value>::type>
98 class PropHandleTag {};
99 
100 template <typename T> struct is_prop_handle_tag : std::false_type {};
101 template<typename T>
102 struct is_prop_handle_tag<PropHandleTag<T>> : std::true_type {};
103 
104 template<typename T>
105 using is_handle_tag = std::enable_if<is_entity<T>::value || is_prop_handle_tag<T>::value>;
106 
107 
108 template<typename EntityTag, typename = typename is_handle_tag<EntityTag>::type>
110 {
111 public:
112  using Entity = EntityTag;
113  explicit constexpr HandleT(int _idx = -1) : OpenVolumeMeshHandle(_idx) {}
114 
115  static HandleT<EntityTag>
116  from_unsigned(size_t _idx)
117  {
118  if (_idx <= static_cast<size_t>(std::numeric_limits<int>::max())) {
119  return HandleT<EntityTag>(static_cast<int>(_idx));
120  } else {
121  assert(false);
122  return HandleT<EntityTag>(-1);
123  }
124  }
125 };
126 
127 // Default entity handles
128 //
129 template class OVM_EXPORT HandleT<Entity::Vertex>;
130 template class OVM_EXPORT HandleT<Entity::HalfEdge>;
131 template class OVM_EXPORT HandleT<Entity::Edge>;
132 template class OVM_EXPORT HandleT<Entity::HalfFace>;
133 template class OVM_EXPORT HandleT<Entity::Face>;
134 template class OVM_EXPORT HandleT<Entity::Cell>;
135 template class OVM_EXPORT HandleT<Entity::Mesh>;
136 
137 using VertexHandle = HandleT<Entity::Vertex>;
138 using HalfEdgeHandle = HandleT<Entity::HalfEdge>;
139 using EdgeHandle = HandleT<Entity::Edge>;
140 using HalfFaceHandle = HandleT<Entity::HalfFace>;
141 using FaceHandle = HandleT<Entity::Face>;
142 using CellHandle = HandleT<Entity::Cell>;
143 using MeshHandle = HandleT<Entity::Mesh>;
144 
145 // Helper class that is used to decrease all handles
146 // exceeding a certain threshold
147 
149 public:
150  explicit VHandleCorrection(VertexHandle _thld) : thld_(_thld) {}
151  void correctValue(VertexHandle& _h) {
152  if(_h > thld_) _h.idx(_h.idx() - 1);
153  }
154 private:
155  VertexHandle thld_;
156 };
158 public:
159  explicit HEHandleCorrection(HalfEdgeHandle _thld) : thld_(_thld) {}
160  void correctVecValue(std::vector<HalfEdgeHandle>& _vec) {
161 #if defined(__clang_major__) && (__clang_major__ >= 5)
162  for(std::vector<HalfEdgeHandle>::iterator it = _vec.begin(), end = _vec.end(); it != end; ++it) {
163  correctValue(*it);
164  }
165 #else
166  std::for_each(_vec.begin(), _vec.end(), fun::bind(&HEHandleCorrection::correctValue, this, fun::placeholders::_1));
167 #endif
168  }
169  void correctValue(HalfEdgeHandle& _h) {
170  if(_h > thld_) _h.idx(_h.idx() - 2);
171  }
172 private:
173  HalfEdgeHandle thld_;
174 };
176 public:
177  explicit HFHandleCorrection(HalfFaceHandle _thld) : thld_(_thld) {}
178  void correctVecValue(std::vector<HalfFaceHandle>& _vec) {
179 #if defined(__clang_major__) && (__clang_major__ >= 5)
180  for(std::vector<HalfFaceHandle>::iterator it = _vec.begin(), end = _vec.end(); it != end; ++it) {
181  correctValue(*it);
182  }
183 #else
184  std::for_each(_vec.begin(), _vec.end(), fun::bind(&HFHandleCorrection::correctValue, this, fun::placeholders::_1));
185 #endif
186  }
187  void correctValue(HalfFaceHandle& _h) {
188  if(_h > thld_) _h.idx(_h.idx() - 2);
189  }
190 private:
191  HalfFaceHandle thld_;
192 };
194 public:
195  explicit CHandleCorrection(CellHandle _thld) : thld_(_thld) {}
196  void correctValue(CellHandle& _h) {
197  if(_h > thld_) _h.idx(_h.idx() - 1);
198  }
199 private:
200  CellHandle thld_;
201 };
202 
203 OVM_EXPORT
204 bool operator==(const int& _lhs, const OpenVolumeMeshHandle& _rhs);
205 
206 OVM_EXPORT
207 bool operator==(const unsigned int& _lhs, const OpenVolumeMeshHandle& _rhs);
208 
209 OVM_EXPORT
210 bool operator!=(const int& _lhs, const OpenVolumeMeshHandle& _rhs);
211 
212 OVM_EXPORT
213 bool operator!=(const unsigned int& _lhs, const OpenVolumeMeshHandle& _rhs);
214 
215 OVM_EXPORT
216 std::ostream& operator<<(std::ostream& _ostr, const OpenVolumeMeshHandle& _handle);
217 
218 OVM_EXPORT
219 std::istream& operator>>(std::istream& _istr, OpenVolumeMeshHandle& _handle);
220 
221 } // Namespace OpenVolumeMesh
222 
size_t uidx() const
return unsigned idx - handle must be valid
bool bind(osg::GeometryPtr &_geo, Mesh &_mesh)
Definition: bindT.hh:101