42 #define OPENMESH_ARRAY_KERNEL_C 46 #include <OpenMesh/Core/Mesh/ArrayKernel.hh> 55 template<
typename std_API_Container_VHandlePointer,
56 typename std_API_Container_HHandlePointer,
57 typename std_API_Container_FHandlePointer>
59 std_API_Container_HHandlePointer& hh_to_update,
60 std_API_Container_FHandlePointer& fh_to_update,
61 bool _v,
bool _e,
bool _f)
65 #ifndef OM_GARBAGE_NO_STATUS_WARNING 66 if ( !this->has_vertex_status() )
67 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;
68 if ( !this->has_edge_status() )
69 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;
70 if ( !this->has_face_status() )
71 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;
75 const bool track_vhandles = ( !vh_to_update.empty() );
76 const bool track_hhandles = ( !hh_to_update.empty() );
77 const bool track_fhandles = ( !fh_to_update.empty() );
81 int nV = int(n_vertices());
82 int nE = int(n_edges());
83 int nH = int(2*n_edges());
84 int nF = (int(n_faces()));
86 std::vector<VertexHandle> vh_map;
87 std::vector<HalfedgeHandle> hh_map;
88 std::vector<FaceHandle> fh_map;
90 std::map <int, int> vertex_inverse_map;
91 std::map <int, int> halfedge_inverse_map;
92 std::map <int, int> face_inverse_map;
102 for (i=0; i<nF; ++i) fh_map.push_back(
FaceHandle(i));
105 if (_v && n_vertices() > 0 && this->has_vertex_status() )
118 if ( track_vhandles ) {
119 vertex_inverse_map[i1] = i0;
120 vertex_inverse_map[i0] = -1;
124 std::swap(vertices_[i0], vertices_[i1]);
125 std::swap(vh_map[i0], vh_map[i1]);
135 if (_e && n_edges() > 0 && this->has_edge_status() )
148 if ( track_hhandles ) {
149 halfedge_inverse_map[2*i1] = 2 * i0;
150 halfedge_inverse_map[2*i0] = -1;
152 halfedge_inverse_map[2*i1 + 1] = 2 * i0 + 1;
153 halfedge_inverse_map[2*i0 + 1] = -1;
157 std::swap(edges_[i0], edges_[i1]);
158 std::swap(hh_map[2*i0], hh_map[2*i1]);
159 std::swap(hh_map[2*i0+1], hh_map[2*i1+1]);
161 hprops_swap(2*i0, 2*i1);
162 hprops_swap(2*i0+1, 2*i1+1);
166 eprops_resize(n_edges());
167 hprops_resize(n_halfedges());
172 if (_f && n_faces() > 0 && this->has_face_status() )
185 if ( track_fhandles ) {
186 face_inverse_map[i1] = i0;
187 face_inverse_map[i0] = -1;
191 std::swap(faces_[i0], faces_[i1]);
192 std::swap(fh_map[i0], fh_map[i1]);
197 fprops_resize(n_faces());
204 KernelVertexIter v_it(vertices_begin()), v_end(vertices_end());
207 for (; v_it!=v_end; ++v_it)
210 if (!is_isolated(vh))
212 set_halfedge_handle(vh, hh_map[halfedge_handle(vh).idx()]);
219 for (KernelEdgeIter e_it(edges_begin()); e_it != edges_end(); ++e_it)
221 hh = halfedge_handle(handle(*e_it), 0);
222 set_vertex_handle(hh, vh_map[to_vertex_handle(hh).idx()]);
223 hh = halfedge_handle(handle(*e_it), 1);
224 set_vertex_handle(hh, vh_map[to_vertex_handle(hh).idx()]);
226 for (KernelEdgeIter e_it(edges_begin()); e_it != edges_end(); ++e_it)
228 hh = halfedge_handle(handle(*e_it), 0);
229 set_next_halfedge_handle(hh, hh_map[next_halfedge_handle(hh).idx()]);
232 set_face_handle(hh, fh_map[face_handle(hh).idx()]);
234 hh = halfedge_handle(handle(*e_it), 1);
235 set_next_halfedge_handle(hh, hh_map[next_halfedge_handle(hh).idx()]);
238 set_face_handle(hh, fh_map[face_handle(hh).idx()]);
245 KernelFaceIter f_it(faces_begin()), f_end(faces_end());
248 for (; f_it!=f_end; ++f_it)
251 set_halfedge_handle(fh, hh_map[halfedge_handle(fh).idx()]);
255 const int vertexCount = int(vertices_.size());
256 const int halfedgeCount = int(edges_.size() * 2);
257 const int faceCount = int(faces_.size());
260 typename std_API_Container_VHandlePointer::iterator v_it(vh_to_update.begin()), v_it_end(vh_to_update.end());
261 for(; v_it != v_it_end; ++v_it)
265 if ( (*v_it)->idx() != vh_map[(*v_it)->idx()].idx() ) {
266 *(*v_it) =
VertexHandle(vertex_inverse_map[(*v_it)->idx()]);
269 }
else if ( ((*v_it)->idx() >= vertexCount) && (vertex_inverse_map.find((*v_it)->idx()) == vertex_inverse_map.end()) ) {
276 typename std_API_Container_HHandlePointer::iterator hh_it(hh_to_update.begin()), hh_it_end(hh_to_update.end());
277 for(; hh_it != hh_it_end; ++hh_it)
280 if ( (*hh_it)->idx() != hh_map[(*hh_it)->idx()].idx() ) {
281 *(*hh_it) =
HalfedgeHandle(halfedge_inverse_map[(*hh_it)->idx()]);
284 }
else if ( ((*hh_it)->idx() >= halfedgeCount) && (halfedge_inverse_map.find((*hh_it)->idx()) == halfedge_inverse_map.end()) ) {
291 typename std_API_Container_FHandlePointer::iterator fh_it(fh_to_update.begin()), fh_it_end(fh_to_update.end());
292 for(; fh_it != fh_it_end; ++fh_it)
296 if ( (*fh_it)->idx() != fh_map[(*fh_it)->idx()].idx() ) {
297 *(*fh_it) =
FaceHandle(face_inverse_map[(*fh_it)->idx()]);
300 }
else if ( ((*fh_it)->idx() >= faceCount) && (face_inverse_map.find((*fh_it)->idx()) == face_inverse_map.end()) ) {
Handle for a vertex entity.
void garbage_collection(bool _v=true, bool _e=true, bool _f=true)
garbage collection
Handle for a halfedge entity.
const StatusInfo & status(VertexHandle _vh) const
Status Query API.
void invalidate()
reset handle to be invalid
void vprops_resize(size_t _n) const
Resizes all vertex property vectors to the specified size.
Handle for a face entity.
Handle for a edge entity.
bool is_boundary(HalfedgeHandle _heh) const
Is halfedge _heh a boundary halfedge (is its face handle invalid) ?