Rev 479 | Blame | Last modification | View Log | RSS feed
#include "HalfEdgeHandle.h"
#include "entities.h"
#include "Manifold.h"
#include "VertexHandle.h"
#include "FaceHandle.h"
#include "VertexCirculator.h"
namespace HMesh
{
HalfEdgeHandle::HalfEdgeHandle(Manifold& _m, Hidx _idx)
: m(&_m), idx(_idx)
{}
const VertexHandle HalfEdgeHandle::vert() const
{
return m->vertex_handle(m->halfedges[idx].vert_idx);
}
const HalfEdgeHandle HalfEdgeHandle::next() const
{
return m->halfedge_handle(m->halfedges[idx].next_idx);
}
const HalfEdgeHandle HalfEdgeHandle::prev() const
{
return m->halfedge_handle(m->halfedges[idx].prev_idx);
}
const HalfEdgeHandle HalfEdgeHandle::opp() const
{
return m->halfedge_handle(m->halfedges[idx].opp_idx);
}
const FaceHandle HalfEdgeHandle::face() const
{
return m->face_handle(m->halfedges[idx].face_idx);
}
VertexHandle HalfEdgeHandle::vert()
{
return m->vertex_handle(m->halfedges[idx].vert_idx);
}
HalfEdgeHandle HalfEdgeHandle::next()
{
return m->halfedge_handle(m->halfedges[idx].next_idx);
}
HalfEdgeHandle HalfEdgeHandle::prev()
{
return m->halfedge_handle(m->halfedges[idx].prev_idx);
}
HalfEdgeHandle HalfEdgeHandle::opp()
{
return m->halfedge_handle(m->halfedges[idx].opp_idx);
}
FaceHandle HalfEdgeHandle::face()
{
return m->face_handle(m->halfedges[idx].face_idx);
}
const HalfEdge& HalfEdgeHandle::get() const
{
return m->halfedges[idx];
}
HalfEdge& HalfEdgeHandle::get()
{
return m->halfedges[idx];
}
bool HalfEdgeHandle::operator==(const HalfEdgeHandle& h) const
{
return idx == h.get_idx();
}
bool HalfEdgeHandle::operator!=(const HalfEdgeHandle& h) const
{
return idx != h.get_idx();
}
void HalfEdgeHandle::operator++()
{
++idx;
while(idx < m->halfedges.full_size() && !m->halfedges.in_use(idx))
++idx;
}
void HalfEdgeHandle::operator++(int)
{
++(*this);
}
void HalfEdgeHandle::operator--()
{
--idx;
while(!m->halfedges.in_use(idx))
--idx;
}
void HalfEdgeHandle::operator--(int)
{
--(*this);
}
bool HalfEdgeHandle::is_valid() const
{
return idx != NULL_HALFEDGE_IDX;
}
bool HalfEdgeHandle::in_use() const
{
return m->halfedges.in_use(idx);
}
Hidx HalfEdgeHandle::get_idx() const
{
return idx;
}
Manifold* HalfEdgeHandle::get_manifold() const
{
return m;
}
/* namespace functions for handles */
/* bool is_used(const HalfEdgeHandle& h)
{
if(h.vert().get_idx() != NULL_VERTEX_IDX)
return true;
return false;
}*/
bool is_boundary(HalfEdgeHandle h)
{
return !h.face().is_valid() || !h.opp().face().is_valid();
}
float length(HalfEdgeHandle h)
{
return (h.vert().get().pos - h.opp().vert().get().pos).length();
}
void link(HalfEdgeHandle h0, HalfEdgeHandle h1)
{
h0.get().next_idx = h1.get_idx();
h1.get().prev_idx = h0.get_idx();
}
void glue(HalfEdgeHandle h0, HalfEdgeHandle h1)
{
h0.get().opp_idx = h1.get_idx();
h1.get().opp_idx = h0.get_idx();
}
bool flip(HalfEdgeHandle h)
{
FaceHandle f = h.face();
HalfEdgeHandle ho = h.opp();
FaceHandle fo = ho.face();
if(!f.is_valid() || !fo.is_valid()){
return false;
}
// We can only flip an edge if both incident polygons are triangles.
if(no_edges(f) != 3 || no_edges(fo) !=3){
return false;
}
// non boundary vertices with a valency of less than 4(less than 3 after operation) degenerates mesh.
VertexHandle v = h.vert();
VertexHandle vo = ho.vert();
if((valency(v) < 4 && !is_boundary(v)) || (valency(vo) < 4 && !is_boundary(vo))){
return false;
}
// Disallow flip if vertices being connected already are.
VertexHandle vn = h.next().vert();
VertexHandle von = ho.next().vert();
if(is_connected(vn, von)){
return false;
}
HalfEdgeHandle hn = h.next();
HalfEdgeHandle hp = h.prev();
HalfEdgeHandle hon = ho.next();
HalfEdgeHandle hop = ho.prev();
hop.get().face_idx = f.get_idx();
hp.get().face_idx = fo.get_idx();
f.get().last_idx = h.get_idx();
fo.get().last_idx = ho.get_idx();
link(hn, h);
link(h, hop);
link(hop, hn);
link(hon, ho);
link(ho, hp);
link(hp, hon);
h.get().vert_idx = von.get_idx();
ho.get().vert_idx = vn.get_idx();
v.get().out_idx = hn.get_idx();
vo.get().out_idx = hon.get_idx();
check_boundary_consistency(v);
check_boundary_consistency(vo);
return true;
}
}