首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >添加::OpenMesh中的复杂边缘误差

添加::OpenMesh中的复杂边缘误差
EN

Stack Overflow用户
提问于 2014-06-13 12:22:42
回答 2查看 3.8K关注 0票数 6

我一直在遵循OpenMesh教程第一步-建立一个立方体的一些修改,我使用的是TriMesh而不是PolyMesh,并且正在构建金字塔而不是立方体。

不知怎么的,我得到了我的第二和第三张脸的错误PolymeshT::add_face:complex edge。这些面应该在点(0,0,0,0)和(0,0,1)和点(0,0,0),(0,0,1)和(1,0,0)之间。

当每个面构造为(0,0,0,1,0)和(0,0,0)到(0,0,1)时已经存在两个边,但是我应该能够创建一些边已经存在的面,不是吗?

我已经尝试过的解决方案

  • 改变坐标
  • 使用PolyMesh而不是TriMesh

我找不到我正在做的任何与教程不同的事情。

代码语言:javascript
复制
#include <OpenMesh/Core/IO/MeshIO.hh>
#include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>
typedef OpenMesh::TriMesh_ArrayKernelT<> MyTriMesh;

// Make a pyramid
int main()
{
    MyTriMesh tin;

    // generate vertices
    MyTriMesh::VertexHandle vhandle[4];
    vhandle[0] = tin.add_vertex(MyTriMesh::Point(0, 0, 0));
    vhandle[1] = tin.add_vertex(MyTriMesh::Point(0, 1, 0));
    vhandle[2] = tin.add_vertex(MyTriMesh::Point(1, 0, 0));
    vhandle[3] = tin.add_vertex(MyTriMesh::Point(0, 0, 1));

    // generate (trianglar) faces
    std::vector<MyTriMesh::VertexHandle> face_vhandles;
    face_vhandles.clear();
    face_vhandles.push_back(vhandle[0]);
    face_vhandles.push_back(vhandle[1]);
    face_vhandles.push_back(vhandle[2]);
    tin.add_face(face_vhandles);

    printf("Vertices: %u\nEdges: %u\nTriangles: %u\n",
        tin.n_vertices(), tin.n_edges(), tin.n_faces());

    face_vhandles.clear();
    face_vhandles.push_back(vhandle[0]);
    face_vhandles.push_back(vhandle[1]);
    face_vhandles.push_back(vhandle[3]);
    tin.add_face(face_vhandles);

    printf("Vertices: %u\nEdges: %u\nTriangles: %u\n",
        tin.n_vertices(), tin.n_edges(), tin.n_faces());

    face_vhandles.clear();
    face_vhandles.push_back(vhandle[0]);
    face_vhandles.push_back(vhandle[3]);
    face_vhandles.push_back(vhandle[2]);
    tin.add_face(face_vhandles);

    printf("Vertices: %u\nEdges: %u\nTriangles: %u\n",
        tin.n_vertices(), tin.n_edges(), tin.n_faces());

    face_vhandles.clear();
    face_vhandles.push_back(vhandle[1]);
    face_vhandles.push_back(vhandle[3]);
    face_vhandles.push_back(vhandle[2]);
    tin.add_face(face_vhandles);

    printf("Vertices: %u\nEdges: %u\nTriangles: %u\n",
        tin.n_vertices(), tin.n_edges(), tin.n_faces());

}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-06-16 08:53:29

此错误是由于某些面的顶点按错误的顺序添加造成的。

OpenMesh使用halfedge结构来描述网格的三维结构。Halfedges是顶点之间的方向边。这允许通过跟踪属于面部的哈勒夫来横越面部上的顶点。然而,由于这个原因,顶点被添加到人脸的顺序是非常重要的。

通常,顶点应该总是按逆时针顺序添加.这会导致相邻的面向相反方向指向半边,如左下方的图片所示。如果顶点的排序不一致,则在“A”的下缘或“B”的底部边缘后面有哪些边是模糊的,如右下方的图片所示。

在问题的代码中,面1和面4按逆时针方向排列,面2和面3按顺时针方向排列。简单的修复方法是切换这两个面的第一个和第三个顶点。

代码语言:javascript
复制
face_vhandles.clear();
face_vhandles.push_back(vhandle[3]);
face_vhandles.push_back(vhandle[1]);
face_vhandles.push_back(vhandle[0]);
tin.add_face(face_vhandles);

face_vhandles.clear();
face_vhandles.push_back(vhandle[2]);
face_vhandles.push_back(vhandle[3]);
face_vhandles.push_back(vhandle[0]);
tin.add_face(face_vhandles);
票数 9
EN

Stack Overflow用户

发布于 2021-06-04 09:14:31

为了扩展Cecilia的回答,如果您正在处理生成的数据,并且无法手动修复三角形的方向,那么我提出了一个固定三角形方向的简短算法:

代码语言:javascript
复制
def calc_transitions(path):
    return ((path[0], path[1]),
            (path[1], path[2]),
            (path[2], path[0]))

def swap_path_match(path1, path2):
    tr1 = calc_transitions(path1)
    tr2 = calc_transitions(path2)
    
    for t in tr1:
        try:
            loc = tr2.index(t)
            swapped = (path2[(loc+2)%3], path2[(loc+1)%3], path2[loc])
            print('From', path1, ': matched (', t[0], '->', t[1], ') in', path2)
            print('Swapping', path2, 'to', swapped)
            return swapped
        except ValueError:
            continue
    
    return path2

要使用这一点,只需迭代一遍脸列表:

代码语言:javascript
复制
for i in range(len(mesh)):
    for j in range(i+1, len(mesh)):
        mesh[j] = swap_path_match(mesh[i], mesh[j])

其中‘网格’是一个三元组的列表,例如。

代码语言:javascript
复制
[(1, 2, 3), (2, 3, 4), (4, 3, 5)]

在此列表中,第0元素和第1元素具有冲突的边缘,因此它们将被交换为:

代码语言:javascript
复制
[(1, 2, 3), (4, 3, 2), (4, 3, 5)]

现在与第一和第二元素之间存在冲突,因此它将被替换为:

代码语言:javascript
复制
[(1, 2, 3), (4, 3, 2), (5, 3, 4)]

另一个数字被移到前面的原因只是实现的一个怪癖;如果结果序列是等价的,则没有必要维护原始顺序。

要明确的是,这并不能解决任何边缘连接两个以上三角形的几何图形。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24205196

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档