HalfEdge实现1——Mesh的建立、查询相关操作、Mesh的读入与输出(Paraview可视化)

本文详细介绍了HalfEdge数据结构,用于表示多边形网格。内容包括HalfEdge简介、数据结构定义、Mesh的建立、顶点和边的邻居查询、网格数据的输入输出,并通过Paraview进行可视化。提供了一种从.obj文件读取数据构建Mesh的方法,并能将其保存为.vtk格式。
摘要由CSDN通过智能技术生成

0.前言

本文将从HalfEdge简介、数据结构的定义、mesh的建立、顶点的顶点邻居查询、顶点的面邻居查询、边的邻居查询、网格数据结构的输入与输出、测试结果八个方面。因作者水平有限,文中难免会有错误之处,希望读者批评指正。

1.HalfEdge简介

HalfEdge(半边)是一种用于表示多边形网格(Polygon Mesh)的一种常用方法,它能够表示任意的多边形网格(必须是流形)。HalfEdge将每条无向边分裂为两条有向边。每一条HalfEdge都以逆时针的方式围绕一个面, 因此每一条边界(boundary)可以被看做围绕着一个空面。

HalfEdge优点:即使包含了点、边、面的邻接信息,该数据结构的大小依然是固定的,没有使用动态数组。

HalfEdge的缺点:只能表示流形结构,无法表示非流形结构。

2.数据结构的定义

基本的数据结构有点、边和面

namespace trimesh_type {                //命名空间三角网格
    typedef long index_t;

    struct point_t {                    //顶点
        index_t index;                  //顶点的索引
        float x, y, z;                  //顶点的坐标
    };

    struct edge_t {                     //三角网格中的边
        index_t v[2];                   //存储两个顶点
        index_t& start() {
            return v[0];
        }

        index_t& end() {
            return v[1];
        }

        edge_t() {
            v[0] = v[1] = -1;           //初始化两个顶点的索引
        }
    };

    struct triangle_t {                 //三角形
        point_t v[3];                   //三角形三个顶点
        const point_t& i() const {
            return v[0];
        }
        const point_t& j() const {
            return v[1];
        }
        const point_t& k() const {
            return v[2];
        }
    };
}

半边结构:

struct halfedge_t {
        index_t toVertex;                       //半边所指向的顶点
        index_t face;                           //半边所存储的面(若为边界,存储的面为空)
        index_t edge;                           //所在的无向边
        index_t prev;                           //前一个半边
        index_t oppositeHe;                     //与自己方向相反的半边
        index_t nextHe;                         //下一条半边(逆时针方向)
        halfedge_t() :toVertex(-1),
                    face(-1),
                    edge(-1),
                    oppositeHe(-1),
                    nextHe(-1) {}
    };

 

mesh中包含维护的变量有:

private:
    vector<point_t> mPoints;                                                    //点集
    vector<triangle_t> mTriangles;                                              //三角形网格集合
    vector<halfedge_t> mHalfEdges;                                              //半边集合
    vector<index_t > mVertexHalfEdges;                                          //根据顶点索引获取半边索引
    vector<index_t > mFaceHalfEdges;                                            //根据面的索引获取半边索引
    vector<index_t > mEdgeHalfEdges;                                            //根据无向边的索引获取半边的索引
    typedef map<pair<index_t, index_t>, index_t > directedEdge2indexMap_t;      
    directedEdge2indexMap_t mDirectedEdge2heIndex;                              //根据有向边获取半边索引
};

3.Mesh的建立

输入:想要构建模型的点集以及三角形网格的信息

输出:一个完整的mesh数据结构

但是为了方便地构建出HalfEdge的数据结构,我们还应该提供边的集合,边的集合可以通过点以及三角形网格的信息获取

/**
     * 根据三角形网格的信息输出边的集合
     * 没有准备边集信息时调用此函数
     * @param triangles         三角形网格信息
     * @param edgesOut          输出的边集
     * @return 
     */
    int unorderedEdgesFromTriangles(const vector<triangle_t> &triangles, vector<edge_t> &edgesOut) {
        typedef set<pair<index_t , index_t > > edgeSet_t;       //边集,防止重复建边
        edgeSet_t edges;
        for (index_t t = 0; t < triangles.size(); ++t) {
            edges.insert(make_pair(min(triangles[t].i().index, triangles[t].j().index), max(triangles[t].i().index, triangles[t].j().index)));
            edges.insert(make_pair(min(triangles[t].j().index, triangles[t].k().index), max(triangles[t]
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值