0

I have a Cdt from constrained delaunay triangulation. I need to obtain border edges which should be trivial: edges which have one face only but I don't know how to obtain these in CGAL:

for(Cdt::Finite_edges_iterator eit = cdt.finite_edges_begin(); eit != cdt.finite_edges_end(); ++eit) 
{
    CD_Cdt::Edge ed = *eit;

    ???
} 

enter image description here

  • red lines are the borders

Also one thing, using is_constrained() is useless because I already delete some faces before.

======== EDIT ========

user3146587's answer actually works but since I have deleted some faces I cannot detect the borders anymore:

std::vector<CDT::Face_handle> invalid_fhs;

// ... add faces to invalid_fhs

// I delete all face handles in invalid_fhs

for(int a = invalid_fhs.size() - 1; a >= 0; a--)
{ cdt.delete_face(invalid_fhs[a]); }
azer89
  • 1,529
  • 1
  • 15
  • 29
  • See the documentation for the advanced modifiers of a 2D triangulation data structure: "The following modifiers are required for convenience of the advanced user. They do not guarantee the combinatorial validity of the resulting triangulation." After deleting a face, you would need to triangulate the hole. – user3146587 Mar 20 '14 at 05:51
  • Instead of deleting the faces you are not interested in, you may want to label them as "removed" (the face type needs to be augmented with this information). The 2D triangulation data structure would then keep its integrity. And you could propagate the border of the complete constrained Delaunay triangulation to the subset of valid faces you want to keep. – user3146587 Mar 20 '14 at 05:53
  • thanks man, it's a big help! – azer89 Mar 20 '14 at 05:56

2 Answers2

2

Simply check whether the edge is adjacent to an infinite face. If so, then it is a boundary edge. Reminder: an edge is a pair of a handle to a face adjacent to the edge and the index of the other adjacent face as a neighbor of the first one.

for (CDT::Finite_edges_iterator eit = cdt.finite_edges_begin(); eit != cdt.finite_edges_end(); ++eit) 
{
    const CDT::Face_handle& fh = eit->first;

    if (cdt.is_infinite(fh) || cdt.is_infinite(fh->neighbor(eit->second)))
    {
        // Border edge
    }
}
user3146587
  • 4,250
  • 1
  • 16
  • 25
1

OK I get it,

I found my mistake: Deleting face is a very very bad thing. Since it makes the cdt invalid and mess up everything.

So What I do:

(1) Instead of delete faces I just mark them to be outside the domain :

fit->set_marked(false);

(2) A border edge has one face is in the domain, another isn't :

for (Cdt::Finite_edges_iterator eit = cdt.finite_edges_begin(); eit != cdt.finite_edges_end(); ++eit) 
{
    const Cdt::Face_handle& fh = eit->first;

    int ctr = 0;
    if(fh->is_in_domain())
    {
        ctr++;
    }
    if(fh->neighbor(eit->second)->is_in_domain())
    {
        ctr++;
    }

    if(ctr == 1)
    {
        Cdt::Segment s = cd_cdt.segment(eit);
        // yeah, I get my border !!
    }
}
azer89
  • 1,529
  • 1
  • 15
  • 29