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
This commit is contained in:
@@ -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); }
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user