Graphics 删除某些面后如何获取边界边(CGAL)?

Graphics 删除某些面后如何获取边界边(CGAL)?,graphics,geometry,cgal,Graphics,Geometry,Cgal,我有一个约束delaunay三角剖分的Cdt。我需要获得边界边,这些边应该很简单:只有一个面的边,但我不知道如何在CGAL中获得这些边: for(Cdt::Finite_edges_iterator eit = cdt.finite_edges_begin(); eit != cdt.finite_edges_end(); ++eit) { CD_Cdt::Edge ed = *eit; ??? } 红线是边界 还有一件事,使用is_constrated()是无用的

我有一个约束delaunay三角剖分的Cdt。我需要获得边界边,这些边应该很简单:只有一个面的边,但我不知道如何在CGAL中获得这些边:

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

    ???
} 

  • 红线是边界
还有一件事,使用is_constrated()是无用的,因为我以前已经删除了一些面

==========编辑========

user3146587的答案实际上是可行的,但由于我删除了一些人脸,我无法再检测到边界:

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]); }
std::向量无效\u fhs;
// ... 将面添加到无效的\u fhs
//我删除了无效的\u fhs中的所有面控制柄
对于(int a=invalid_fhs.size()-1;a>=0;a--)
{cdt.delete_face(无效的_fhs[a])}

只需检查边是否与无限面相邻即可。如果是,则它是一条边界边。提醒:边是与边相邻的一个面的一对句柄,另一个相邻面的索引是第一个面的邻居

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
    }
}

只需检查边是否与无限面相邻。如果是,则它是一条边界边。提醒:边是与边相邻的一个面的一对句柄,另一个相邻面的索引是第一个面的邻居

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
    }
}

只需检查边是否与无限面相邻。如果是,则它是一条边界边。提醒:边是与边相邻的一个面的一对句柄,另一个相邻面的索引是第一个面的邻居

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
    }
}

只需检查边是否与无限面相邻。如果是,则它是一条边界边。提醒:边是与边相邻的一个面的一对句柄,另一个相邻面的索引是第一个面的邻居

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
    }
}
好的,我明白了

我发现了我的错误:删除人脸是一件非常非常糟糕的事情。因为这会使cdt无效,并把一切都搞糟。

所以我要做的是:

(1)我没有删除面,而是将它们标记为域外:

fit->set_marked(false);
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 !!
    }
}
(2)边界边有一个面在域中,另一个面不在域中:

fit->set_marked(false);
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 !!
    }
}
好的,我明白了

我发现了我的错误:删除人脸是一件非常非常糟糕的事情。因为这会使cdt无效,并把一切都搞糟。

所以我要做的是:

(1)我没有删除面,而是将它们标记为域外:

fit->set_marked(false);
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 !!
    }
}
(2)边界边有一个面在域中,另一个面不在域中:

fit->set_marked(false);
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 !!
    }
}
好的,我明白了

我发现了我的错误:删除人脸是一件非常非常糟糕的事情。因为这会使cdt无效,并把一切都搞糟。

所以我要做的是:

(1)我没有删除面,而是将它们标记为域外:

fit->set_marked(false);
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 !!
    }
}
(2)边界边有一个面在域中,另一个面不在域中:

fit->set_marked(false);
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 !!
    }
}
好的,我明白了

我发现了我的错误:删除人脸是一件非常非常糟糕的事情。因为这会使cdt无效,并把一切都搞糟。

所以我要做的是:

(1)我没有删除面,而是将它们标记为域外:

fit->set_marked(false);
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 !!
    }
}
(2)边界边有一个面在域中,另一个面不在域中:

fit->set_marked(false);
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 !!
    }
}

有关二维三角测量数据结构的高级修改器,请参阅文档:“为方便高级用户,需要以下修改器。它们不保证生成的三角测量的组合有效性。”删除面后,您需要对孔进行三角剖分。您可能不想删除不感兴趣的面,而是希望将其标记为“已删除”(面类型需要使用此信息进行扩充)。二维三角测量数据结构将保持其完整性。您可以将完整约束Delaunay三角剖分的边界传播到您想要保留的有效面的子集。谢谢,伙计,这是一个很大的帮助!有关二维三角测量数据结构的高级修改器,请参阅文档:“为方便高级用户,需要以下修改器。它们不保证生成的三角测量的组合有效性。”删除面后,您需要对孔进行三角剖分。您可能不想删除不感兴趣的面,而是希望将其标记为“已删除”(面类型需要使用此信息进行扩充)。二维三角测量数据结构将保持其完整性。您可以将完整约束Delaunay三角剖分的边界传播到您想要保留的有效面的子集。谢谢,伙计,这是一个很大的帮助!有关二维三角测量数据结构的高级修改器,请参阅文档:“为方便高级用户,需要以下修改器。它们不保证生成的三角测量的组合有效性。”删除面后,您需要对孔进行三角剖分。您可能不想删除不感兴趣的面,而是希望将其标记为“已删除”(面类型需要使用此信息进行扩充)。二维三角测量数据结构将保持其完整性。您可以将完整约束Delaunay三角剖分的边界传播到您想要保留的有效面的子集。谢谢,伙计,这是一个很大的帮助!有关二维三角测量数据结构的高级修改器,请参阅文档:“为方便高级用户,需要以下修改器。它们不保证生成的三角测量的组合有效性。”删除面后,您需要对孔进行三角剖分。您可能不想删除不感兴趣的面,而是希望将其标记为“已删除”(面类型需要使用此信息进行扩充)。二维三角测量数据结构将保持其完整性。您可以将完整约束Delaunay三角剖分的边界传播到您想要保留的有效面的子集。谢谢,伙计,这是一个很大的帮助!