Commit 727157ba authored by Jan Möbius's avatar Jan Möbius
Browse files

Don't crash in garbage collection, if certain status flags are not available



git-svn-id: http://www.openmesh.org/svnrepo/OpenMesh/trunk@658 fdac6126-5c0c-442c-9429-916003d36597
parent 7824deb5
...@@ -61,181 +61,182 @@ void ArrayKernel::garbage_collection(std_API_Container_VHandlePointer& vh_to_upd ...@@ -61,181 +61,182 @@ void ArrayKernel::garbage_collection(std_API_Container_VHandlePointer& vh_to_upd
std_API_Container_FHandlePointer& fh_to_update, std_API_Container_FHandlePointer& fh_to_update,
bool _v, bool _e, bool _f) bool _v, bool _e, bool _f)
{ {
int i, i0, i1, nV(n_vertices()), nE(n_edges()), nH(2*n_edges()), nF(n_faces());
std::vector<VertexHandle> vh_map; int i, i0, i1, nV(n_vertices()), nE(n_edges()), nH(2*n_edges()), nF(n_faces());
std::vector<HalfedgeHandle> hh_map;
std::vector<FaceHandle> fh_map;
// setup handle mapping: std::vector<VertexHandle> vh_map;
vh_map.reserve(nV); std::vector<HalfedgeHandle> hh_map;
for (i=0; i<nV; ++i) vh_map.push_back(VertexHandle(i)); std::vector<FaceHandle> fh_map;
hh_map.reserve(nH); // setup handle mapping:
for (i=0; i<nH; ++i) hh_map.push_back(HalfedgeHandle(i)); vh_map.reserve(nV);
for (i=0; i<nV; ++i) vh_map.push_back(VertexHandle(i));
fh_map.reserve(nF); hh_map.reserve(nH);
for (i=0; i<nF; ++i) fh_map.push_back(FaceHandle(i)); for (i=0; i<nH; ++i) hh_map.push_back(HalfedgeHandle(i));
// remove deleted vertices fh_map.reserve(nF);
if (_v && n_vertices() > 0) for (i=0; i<nF; ++i) fh_map.push_back(FaceHandle(i));
{
i0=0; i1=nV-1;
while (1)
{
// find 1st deleted and last un-deleted
while (!status(VertexHandle(i0)).deleted() && i0 < i1) ++i0;
while ( status(VertexHandle(i1)).deleted() && i0 < i1) --i1;
if (i0 >= i1) break;
// swap
std::swap(vertices_[i0], vertices_[i1]);
std::swap(vh_map[i0], vh_map[i1]);
vprops_swap(i0, i1);
};
vertices_.resize(status(VertexHandle(i0)).deleted() ? i0 : i0+1);
vprops_resize(n_vertices());
}
// remove deleted vertices
if (_v && n_vertices() > 0 && this->has_vertex_status() )
{
i0=0; i1=nV-1;
// remove deleted edges while (1)
if (_e && n_edges() > 0)
{ {
i0=0; i1=nE-1; // find 1st deleted and last un-deleted
while (!status(VertexHandle(i0)).deleted() && i0 < i1) ++i0;
while (1) while ( status(VertexHandle(i1)).deleted() && i0 < i1) --i1;
{ if (i0 >= i1) break;
// find 1st deleted and last un-deleted
while (!status(EdgeHandle(i0)).deleted() && i0 < i1) ++i0;
while ( status(EdgeHandle(i1)).deleted() && i0 < i1) --i1;
if (i0 >= i1) break;
// swap
std::swap(edges_[i0], edges_[i1]);
std::swap(hh_map[2*i0], hh_map[2*i1]);
std::swap(hh_map[2*i0+1], hh_map[2*i1+1]);
eprops_swap(i0, i1);
hprops_swap(2*i0, 2*i1);
hprops_swap(2*i0+1, 2*i1+1);
};
edges_.resize(status(EdgeHandle(i0)).deleted() ? i0 : i0+1);
eprops_resize(n_edges());
hprops_resize(n_halfedges());
}
// swap
std::swap(vertices_[i0], vertices_[i1]);
std::swap(vh_map[i0], vh_map[i1]);
vprops_swap(i0, i1);
};
// remove deleted faces vertices_.resize(status(VertexHandle(i0)).deleted() ? i0 : i0+1);
if (_f && n_faces() > 0) vprops_resize(n_vertices());
{ }
i0=0; i1=nF-1;
while (1)
{
// find 1st deleted and last un-deleted
while (!status(FaceHandle(i0)).deleted() && i0 < i1) ++i0;
while ( status(FaceHandle(i1)).deleted() && i0 < i1) --i1;
if (i0 >= i1) break;
// swap
std::swap(faces_[i0], faces_[i1]);
std::swap(fh_map[i0], fh_map[i1]);
fprops_swap(i0, i1);
};
faces_.resize(status(FaceHandle(i0)).deleted() ? i0 : i0+1);
fprops_resize(n_faces());
}
// update handles of vertices // remove deleted edges
if (_e) if (_e && n_edges() > 0 && this->has_edge_status() )
{
i0=0; i1=nE-1;
while (1)
{ {
KernelVertexIter v_it(vertices_begin()), v_end(vertices_end()); // find 1st deleted and last un-deleted
VertexHandle vh; while (!status(EdgeHandle(i0)).deleted() && i0 < i1) ++i0;
while ( status(EdgeHandle(i1)).deleted() && i0 < i1) --i1;
for (; v_it!=v_end; ++v_it) if (i0 >= i1) break;
{
vh = handle(*v_it); // swap
if (!is_isolated(vh)) std::swap(edges_[i0], edges_[i1]);
{ std::swap(hh_map[2*i0], hh_map[2*i1]);
set_halfedge_handle(vh, hh_map[halfedge_handle(vh).idx()]); std::swap(hh_map[2*i0+1], hh_map[2*i1+1]);
} eprops_swap(i0, i1);
} hprops_swap(2*i0, 2*i1);
} hprops_swap(2*i0+1, 2*i1+1);
};
edges_.resize(status(EdgeHandle(i0)).deleted() ? i0 : i0+1);
eprops_resize(n_edges());
hprops_resize(n_halfedges());
}
// remove deleted faces
if (_f && n_faces() > 0 && this->has_face_status() )
{
i0=0; i1=nF-1;
while (1)
{
// find 1st deleted and last un-deleted
while (!status(FaceHandle(i0)).deleted() && i0 < i1) ++i0;
while ( status(FaceHandle(i1)).deleted() && i0 < i1) --i1;
if (i0 >= i1) break;
HalfedgeHandle hh; // swap
// update handles of halfedges std::swap(faces_[i0], faces_[i1]);
for (KernelEdgeIter e_it(edges_begin()); e_it != edges_end(); ++e_it) std::swap(fh_map[i0], fh_map[i1]);
{//in the first pass update the (half)edges vertices fprops_swap(i0, i1);
hh = halfedge_handle(handle(*e_it), 0); };
set_vertex_handle(hh, vh_map[to_vertex_handle(hh).idx()]);
hh = halfedge_handle(handle(*e_it), 1);
set_vertex_handle(hh, vh_map[to_vertex_handle(hh).idx()]);
}
for (KernelEdgeIter e_it(edges_begin()); e_it != edges_end(); ++e_it)
{//in the second pass update the connectivity of the (half)edges
hh = halfedge_handle(handle(*e_it), 0);
set_next_halfedge_handle(hh, hh_map[next_halfedge_handle(hh).idx()]);
if (!is_boundary(hh))
{
set_face_handle(hh, fh_map[face_handle(hh).idx()]);
}
hh = halfedge_handle(handle(*e_it), 1);
set_next_halfedge_handle(hh, hh_map[next_halfedge_handle(hh).idx()]);
if (!is_boundary(hh))
{
set_face_handle(hh, fh_map[face_handle(hh).idx()]);
}
}
// update handles of faces faces_.resize(status(FaceHandle(i0)).deleted() ? i0 : i0+1);
if (_e) fprops_resize(n_faces());
{ }
KernelFaceIter f_it(faces_begin()), f_end(faces_end());
FaceHandle fh;
for (; f_it!=f_end; ++f_it)
{
fh = handle(*f_it);
set_halfedge_handle(fh, hh_map[halfedge_handle(fh).idx()]);
}
}
const int vertexCount = vertices_.size();
const int halfedgeCount = edges_.size() * 2;
const int faceCount = faces_.size();
// Update the vertex handles in the vertex handle vector // update handles of vertices
typename std_API_Container_VHandlePointer::iterator v_it(vh_to_update.begin()), v_it_end(vh_to_update.end()); if (_e)
for(; v_it != v_it_end; ++v_it) {
KernelVertexIter v_it(vertices_begin()), v_end(vertices_end());
VertexHandle vh;
for (; v_it!=v_end; ++v_it)
{ {
if ( (*v_it)->idx() >= vertexCount ) vh = handle(*v_it);
(*v_it)->invalidate(); if (!is_isolated(vh))
else {
*(*v_it) = vh_map[(*v_it)->idx()]; set_halfedge_handle(vh, hh_map[halfedge_handle(vh).idx()]);
}
} }
}
// Update the halfedge handles in the halfedge handle vector
typename std_API_Container_HHandlePointer::iterator hh_it(hh_to_update.begin()), hh_it_end(hh_to_update.end()); HalfedgeHandle hh;
for(; hh_it != hh_it_end; ++hh_it) // update handles of halfedges
for (KernelEdgeIter e_it(edges_begin()); e_it != edges_end(); ++e_it)
{//in the first pass update the (half)edges vertices
hh = halfedge_handle(handle(*e_it), 0);
set_vertex_handle(hh, vh_map[to_vertex_handle(hh).idx()]);
hh = halfedge_handle(handle(*e_it), 1);
set_vertex_handle(hh, vh_map[to_vertex_handle(hh).idx()]);
}
for (KernelEdgeIter e_it(edges_begin()); e_it != edges_end(); ++e_it)
{//in the second pass update the connectivity of the (half)edges
hh = halfedge_handle(handle(*e_it), 0);
set_next_halfedge_handle(hh, hh_map[next_halfedge_handle(hh).idx()]);
if (!is_boundary(hh))
{ {
if ( (*hh_it)->idx() >= halfedgeCount ) set_face_handle(hh, fh_map[face_handle(hh).idx()]);
(*hh_it)->invalidate();
else
*(*hh_it) = hh_map[(*hh_it)->idx()];
} }
// Update the face handles in the face handle vector hh = halfedge_handle(handle(*e_it), 1);
typename std_API_Container_FHandlePointer::iterator fh_it(fh_to_update.begin()), fh_it_end(fh_to_update.end()); set_next_halfedge_handle(hh, hh_map[next_halfedge_handle(hh).idx()]);
for(; fh_it != fh_it_end; ++fh_it) if (!is_boundary(hh))
{
set_face_handle(hh, fh_map[face_handle(hh).idx()]);
}
}
// update handles of faces
if (_e)
{
KernelFaceIter f_it(faces_begin()), f_end(faces_end());
FaceHandle fh;
for (; f_it!=f_end; ++f_it)
{ {
if ( (*fh_it)->idx() >= faceCount ) fh = handle(*f_it);
(*fh_it)->invalidate(); set_halfedge_handle(fh, hh_map[halfedge_handle(fh).idx()]);
else
*(*fh_it) = fh_map[(*fh_it)->idx()];
} }
}
const int vertexCount = vertices_.size();
const int halfedgeCount = edges_.size() * 2;
const int faceCount = faces_.size();
// Update the vertex handles in the vertex handle vector
typename std_API_Container_VHandlePointer::iterator v_it(vh_to_update.begin()), v_it_end(vh_to_update.end());
for(; v_it != v_it_end; ++v_it)
{
if ( (*v_it)->idx() >= vertexCount )
(*v_it)->invalidate();
else
*(*v_it) = vh_map[(*v_it)->idx()];
}
// Update the halfedge handles in the halfedge handle vector
typename std_API_Container_HHandlePointer::iterator hh_it(hh_to_update.begin()), hh_it_end(hh_to_update.end());
for(; hh_it != hh_it_end; ++hh_it)
{
if ( (*hh_it)->idx() >= halfedgeCount )
(*hh_it)->invalidate();
else
*(*hh_it) = hh_map[(*hh_it)->idx()];
}
// Update the face handles in the face handle vector
typename std_API_Container_FHandlePointer::iterator fh_it(fh_to_update.begin()), fh_it_end(fh_to_update.end());
for(; fh_it != fh_it_end; ++fh_it)
{
if ( (*fh_it)->idx() >= faceCount )
(*fh_it)->invalidate();
else
*(*fh_it) = fh_map[(*fh_it)->idx()];
}
} }
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment