49 #define OPENMESH_ARRAY_KERNEL_C
53 #include <OpenMesh/Core/Mesh/ArrayKernel.hh>
62 template<
typename std_API_Container_VHandlePointer,
63 typename std_API_Container_HHandlePointer,
64 typename std_API_Container_FHandlePointer>
66 std_API_Container_HHandlePointer& hh_to_update,
67 std_API_Container_FHandlePointer& fh_to_update,
68 bool _v,
bool _e,
bool _f)
72 #ifndef OM_GARBAGE_NO_STATUS_WARNING
73 if ( !this->has_vertex_status() )
74 omerr() <<
"garbage_collection: No vertex status available. You can request it: mesh.request_vertex_status() or define OM_GARBAGE_NO_STATUS_WARNING to silence this warning." << std::endl;
75 if ( !this->has_edge_status() )
76 omerr() <<
"garbage_collection: No edge status available. You can request it: mesh.request_edge_status() or define OM_GARBAGE_NO_STATUS_WARNING to silence this warning." << std::endl;
77 if ( !this->has_face_status() )
78 omerr() <<
"garbage_collection: No face status available. You can request it: mesh.request_face_status() or define OM_GARBAGE_NO_STATUS_WARNING to silence this warning." << std::endl;
82 const bool track_vhandles = ( !vh_to_update.empty() );
83 const bool track_hhandles = ( !hh_to_update.empty() );
84 const bool track_fhandles = ( !fh_to_update.empty() );
88 int nV = int(n_vertices());
89 int nE = int(n_edges());
90 int nH = int(2*n_edges());
91 int nF = (int(n_faces()));
93 std::vector<VertexHandle> vh_map;
94 std::vector<HalfedgeHandle> hh_map;
95 std::vector<FaceHandle> fh_map;
97 std::map <int, int> vertex_inverse_map;
98 std::map <int, int> halfedge_inverse_map;
99 std::map <int, int> face_inverse_map;
109 for (i=0; i<nF; ++i) fh_map.push_back(
FaceHandle(i));
112 if (_v && n_vertices() > 0 && this->has_vertex_status() )
125 if ( track_vhandles ) {
126 vertex_inverse_map[i1] = i0;
127 vertex_inverse_map[i0] = -1;
131 std::swap(vertices_[i0], vertices_[i1]);
132 std::swap(vh_map[i0], vh_map[i1]);
142 if (_e && n_edges() > 0 && this->has_edge_status() )
155 if ( track_hhandles ) {
156 halfedge_inverse_map[2*i1] = 2 * i0;
157 halfedge_inverse_map[2*i0] = -1;
159 halfedge_inverse_map[2*i1 + 1] = 2 * i0 + 1;
160 halfedge_inverse_map[2*i0 + 1] = -1;
164 std::swap(edges_[i0], edges_[i1]);
165 std::swap(hh_map[2*i0], hh_map[2*i1]);
166 std::swap(hh_map[2*i0+1], hh_map[2*i1+1]);
168 hprops_swap(2*i0, 2*i1);
169 hprops_swap(2*i0+1, 2*i1+1);
173 eprops_resize(n_edges());
174 hprops_resize(n_halfedges());
179 if (_f && n_faces() > 0 && this->has_face_status() )
192 if ( track_fhandles ) {
193 face_inverse_map[i1] = i0;
194 face_inverse_map[i0] = -1;
198 std::swap(faces_[i0], faces_[i1]);
199 std::swap(fh_map[i0], fh_map[i1]);
204 fprops_resize(n_faces());
211 KernelVertexIter v_it(vertices_begin()), v_end(vertices_end());
214 for (; v_it!=v_end; ++v_it)
217 if (!is_isolated(vh))
219 set_halfedge_handle(vh, hh_map[halfedge_handle(vh).idx()]);
226 for (KernelEdgeIter e_it(edges_begin()); e_it != edges_end(); ++e_it)
228 hh = halfedge_handle(handle(*e_it), 0);
229 set_vertex_handle(hh, vh_map[to_vertex_handle(hh).idx()]);
230 hh = halfedge_handle(handle(*e_it), 1);
231 set_vertex_handle(hh, vh_map[to_vertex_handle(hh).idx()]);
233 for (KernelEdgeIter e_it(edges_begin()); e_it != edges_end(); ++e_it)
235 hh = halfedge_handle(handle(*e_it), 0);
236 set_next_halfedge_handle(hh, hh_map[next_halfedge_handle(hh).idx()]);
239 set_face_handle(hh, fh_map[face_handle(hh).idx()]);
241 hh = halfedge_handle(handle(*e_it), 1);
242 set_next_halfedge_handle(hh, hh_map[next_halfedge_handle(hh).idx()]);
245 set_face_handle(hh, fh_map[face_handle(hh).idx()]);
252 KernelFaceIter f_it(faces_begin()), f_end(faces_end());
255 for (; f_it!=f_end; ++f_it)
258 set_halfedge_handle(fh, hh_map[halfedge_handle(fh).idx()]);
262 const int vertexCount = int(vertices_.size());
263 const int halfedgeCount = int(edges_.size() * 2);
264 const int faceCount = int(faces_.size());
267 typename std_API_Container_VHandlePointer::iterator v_it(vh_to_update.begin()), v_it_end(vh_to_update.end());
268 for(; v_it != v_it_end; ++v_it)
272 if ( (*v_it)->idx() != vh_map[(*v_it)->idx()].idx() ) {
273 *(*v_it) =
VertexHandle(vertex_inverse_map[(*v_it)->idx()]);
276 }
else if ( ((*v_it)->idx() >= vertexCount) && (vertex_inverse_map.find((*v_it)->idx()) == vertex_inverse_map.end()) ) {
283 typename std_API_Container_HHandlePointer::iterator hh_it(hh_to_update.begin()), hh_it_end(hh_to_update.end());
284 for(; hh_it != hh_it_end; ++hh_it)
287 if ( (*hh_it)->idx() != hh_map[(*hh_it)->idx()].idx() ) {
288 *(*hh_it) =
HalfedgeHandle(halfedge_inverse_map[(*hh_it)->idx()]);
291 }
else if ( ((*hh_it)->idx() >= halfedgeCount) && (halfedge_inverse_map.find((*hh_it)->idx()) == halfedge_inverse_map.end()) ) {
298 typename std_API_Container_FHandlePointer::iterator fh_it(fh_to_update.begin()), fh_it_end(fh_to_update.end());
299 for(; fh_it != fh_it_end; ++fh_it)
303 if ( (*fh_it)->idx() != fh_map[(*fh_it)->idx()].idx() ) {
304 *(*fh_it) =
FaceHandle(face_inverse_map[(*fh_it)->idx()]);
307 }
else if ( ((*fh_it)->idx() >= faceCount) && (face_inverse_map.find((*fh_it)->idx()) == face_inverse_map.end()) ) {
void garbage_collection(bool _v=true, bool _e=true, bool _f=true)
garbage collection
const StatusInfo & status(VertexHandle _vh) const
Status Query API.
Handle for a halfedge entity.
bool is_boundary(HalfedgeHandle _heh) const
Is halfedge _heh a boundary halfedge (is its face handle invalid) ?
Handle for a vertex entity.
Handle for a edge entity.
Handle for a face entity.
void invalidate()
reset handle to be invalid
void vprops_resize(size_t _n) const
Resizes all vertex property vectors to the specified size.