Commit 39f1eecc authored by Jan Möbius's avatar Jan Möbius
Browse files

Added is_collapse_ok and split_edge for polymeshes

git-svn-id: http://www.openmesh.org/svnrepo/OpenMesh/trunk@396 fdac6126-5c0c-442c-9429-916003d36597
parent 92d0d9b3
......@@ -287,6 +287,140 @@ PolyConnectivity::add_face(const VertexHandle* _vertex_handles, uint _vhs_size)
return fh;
}
//-----------------------------------------------------------------------------
bool PolyConnectivity::is_collapse_ok(HalfedgeHandle v0v1)
{
HalfedgeHandle v1v0(opposite_halfedge_handle(v0v1));
VertexHandle v0(to_vertex_handle(v1v0));
VertexHandle v1(to_vertex_handle(v0v1));
bool v0v1_triangle = false;
bool v1v0_triangle = false;
if (!is_boundary(v0v1))
v0v1_triangle = valence(face_handle(v0v1)) == 3;
if (!is_boundary(v1v0))
v1v0_triangle = valence(face_handle(v1v0)) == 3;
//in a quadmesh we dont have the "next" or "previous" vhandle, so we need to look at previous and next on both sides
VertexHandle v_01_p = from_vertex_handle(prev_halfedge_handle(v0v1));
VertexHandle v_01_n = to_vertex_handle(next_halfedge_handle(v0v1));
VertexHandle v_10_p = from_vertex_handle(prev_halfedge_handle(v1v0));
VertexHandle v_10_n = to_vertex_handle(next_halfedge_handle(v1v0));
//is edge already deleteed?
if (status(edge_handle(v0v1)).deleted())
{
return false;
}
//are the vertices already deleted ?
if (status(v0).deleted() || status(v1).deleted())
{
return false;
}
//the edges v1-vl and vl-v0 must not be both boundary edges
//this test makes only sense in a polymesh if the side face is a triangle
if (!is_boundary(v0v1))
{
if (v0v1_triangle)
{
VertexHandle vl = to_vertex_handle(next_halfedge_handle(v0v1));
HalfedgeHandle h1 = next_halfedge_handle(v0v1);
HalfedgeHandle h2 = next_halfedge_handle(h1);
if (is_boundary(opposite_halfedge_handle(h1)) && is_boundary(opposite_halfedge_handle(h2)))
return false;
}
}
//the edges v0-vr and vr-v1 must not be both boundary edges
//this test makes only sense in a polymesh if the side face is a triangle
if (!is_boundary(v1v0))
{
if (v1v0_triangle)
{
VertexHandle vr = to_vertex_handle(next_halfedge_handle(v1v0));
HalfedgeHandle h1 = next_halfedge_handle(v1v0);
HalfedgeHandle h2 = next_halfedge_handle(h1);
if (is_boundary(opposite_halfedge_handle(h1)) && is_boundary(opposite_halfedge_handle(h2)))
return false;
}
}
// edge between two boundary vertices should be a boundary edge
if ( is_boundary(v0) && is_boundary(v1) && !is_boundary(v0v1) && !is_boundary(v1v0))
return false;
VertexVertexIter vv_it;
// test intersection of the one-rings of v0 and v1
for (vv_it = vv_iter(v0); vv_it; ++vv_it)
{
status(vv_it).set_tagged(false);
}
for (vv_it = vv_iter(v1); vv_it; ++vv_it)
{
status(vv_it).set_tagged(true);
}
for (vv_it = vv_iter(v0); vv_it; ++vv_it)
{
if (status(vv_it).tagged() &&
!(vv_it.handle() == v_01_n && v0v1_triangle) &&
!(vv_it.handle() == v_10_n && v1v0_triangle)
)
{
return false;
}
}
//test for a face on the backside/other side that might degenerate
if (v0v1_triangle)
{
HalfedgeHandle one, two;
one = next_halfedge_handle(v0v1);
two = next_halfedge_handle(one);
one = opposite_halfedge_handle(one);
two = opposite_halfedge_handle(two);
if (face_handle(one) == face_handle(two) && valence(face_handle(one)) != 3)
{
return false;
}
}
if (v1v0_triangle)
{
HalfedgeHandle one, two;
one = next_halfedge_handle(v1v0);
two = next_halfedge_handle(one);
one = opposite_halfedge_handle(one);
two = opposite_halfedge_handle(two);
if (face_handle(one) == face_handle(two) && valence(face_handle(one)) != 3)
{
return false;
}
}
if (status(vv_it).tagged() && v_01_n == v_10_n && v0v1_triangle && v1v0_triangle)
{
return false;
}
// passed all tests
return true;
}
//-----------------------------------------------------------------------------
void PolyConnectivity::delete_vertex(VertexHandle _vh, bool _delete_isolated_vertices)
......@@ -850,5 +984,63 @@ uint PolyConnectivity::valence(FaceHandle _fh) const
return count;
}
//-----------------------------------------------------------------------------
void PolyConnectivity::split_edge(EdgeHandle _eh, VertexHandle _vh)
{
HalfedgeHandle h0 = halfedge_handle(_eh, 0);
HalfedgeHandle h1 = halfedge_handle(_eh, 1);
VertexHandle vfrom = from_vertex_handle(h0);
HalfedgeHandle ph0 = prev_halfedge_handle(h0);
HalfedgeHandle ph1 = prev_halfedge_handle(h1);
HalfedgeHandle nh0 = next_halfedge_handle(h0);
HalfedgeHandle nh1 = next_halfedge_handle(h1);
bool boundary0 = is_boundary(h0);
bool boundary1 = is_boundary(h1);
//add the new edge
HalfedgeHandle new_e = new_edge(from_vertex_handle(h0), _vh);
//fix the vertex of the opposite halfedge
set_vertex_handle(h1, _vh);
//fix the halfedge connectivity
set_next_halfedge_handle(new_e, h0);
set_next_halfedge_handle(h1, opposite_halfedge_handle(new_e));
set_next_halfedge_handle(ph0, new_e);
set_next_halfedge_handle(opposite_halfedge_handle(new_e), nh1);
set_prev_halfedge_handle(new_e, ph0);
set_prev_halfedge_handle(opposite_halfedge_handle(new_e), h1);
set_prev_halfedge_handle(nh1, opposite_halfedge_handle(new_e));
set_prev_halfedge_handle(h0, new_e);
if (!boundary0)
{
set_face_handle(new_e, face_handle(h0));
} else
{
set_boundary(new_e);
}
if (!boundary1)
{
set_face_handle(opposite_halfedge_handle(new_e), face_handle(h1));
}
{
set_boundary(opposite_halfedge_handle(new_e));
}
if (halfedge_handle(vfrom) == h0)
{
set_halfedge_handle(vfrom, new_e);
}
}
}//namespace OpenMesh
......@@ -236,6 +236,13 @@ public:
/// \name Deleting mesh items and other connectivity/topology modifications
//@{
/** Returns whether collapsing halfedge _heh is ok or would lead to
topological inconsistencies.
\attention This method need the Attributes::Status attribute and
changes the \em tagged bit. */
bool is_collapse_ok(HalfedgeHandle _he);
/** Mark vertex and all incident edges and faces deleted.
Items marked deleted will be removed by garbageCollection().
\attention Needs the Attributes::Status attribute for vertices,
......@@ -657,6 +664,9 @@ public:
/// triangulate the entire mesh
void triangulate();
/// Edge split (inserts a vertex on the edge only)
void split_edge(EdgeHandle _eh, VertexHandle _vh);
/** \name Generic handle derefertiation.
Calls the respective vertex(), halfedge(), edge(), face()
......
......@@ -430,10 +430,11 @@ public:
{ Kernel::split(_fh, _vh); }
inline void split(EdgeHandle _eh, const Point& _p)
{ Kernel::split(_eh, add_vertex(_p)); }
{ Kernel::split_edge(_eh, add_vertex(_p)); }
inline void split(EdgeHandle _eh, VertexHandle _vh)
{ Kernel::split(_eh, _vh); }
{ Kernel::split_edge(_eh, _vh); }
};
......
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