Dandelion 1.1.1
A light-weight 3D builder for educational usage
载入中...
搜索中...
未找到
HalfedgeMesh类 参考

半边网格整体。 更多...

#include <halfedge.h>

struct  EdgeRecord
 在曲面简化算法中用到的工具类。 更多...
 

Public 成员函数

 HalfedgeMesh (Object &object)
 
 HalfedgeMesh (HalfedgeMesh &other)=delete
 
 ~HalfedgeMesh ()
 
void sync ()
 
void render (const Shader &shader)
 
std::optional< Edge * > flip_edge (Edge *e)
 翻转一条边。
 
std::optional< Vertex * > split_edge (Edge *e)
 分裂一条边。
 
std::optional< Vertex * > collapse_edge (Edge *e)
 坍缩一条边。
 
void loop_subdivide ()
 执行一次 Loop 曲面细分。
 
void simplify ()
 执行一次曲面简化。
 
void isotropic_remesh ()
 执行一次重网格化。
 

静态 Public 成员函数

static std::tuple< Eigen::Vector3f, Eigen::Vector3f > halfedge_arrow_endpoints (const Halfedge *h)
 

Public 属性

LinkedList< Halfedgehalfedges
 
LinkedList< Vertexvertices
 
LinkedList< Edgeedges
 
LinkedList< Facefaces
 
std::vector< Vertex * > v_pointers
 
std::variant< std::monostate, Vertex *, Edge *, Face * > inconsistent_element
 当前处于不一致状态的几何基本元素。
 
bool global_inconsistent
 
std::optional< HalfedgeMeshFailureerror_info
 

Private 成员函数

Halfedgenew_halfedge ()
 
Vertexnew_vertex ()
 
Edgenew_edge ()
 
Facenew_face (bool is_boundary=false)
 
void regenerate_halfedge_arrows ()
 
void erase (Halfedge *h)
 
void erase (Vertex *v)
 
void erase (Edge *e)
 
void erase (Face *f)
 
void clear_erasure_records ()
 释放内存并清除已删除元素的记录。
 
std::optional< HalfedgeMeshFailurevalidate ()
 检查半边网格的状态。
 

Private 属性

Objectobject
 
GL::Meshmesh
 
std::unordered_map< size_t, Halfedge * > erased_halfedges
 
std::unordered_map< size_t, Vertex * > erased_vertices
 
std::unordered_map< size_t, Edge * > erased_edges
 
std::unordered_map< size_t, Face * > erased_faces
 
std::unordered_map< const Vertex *, size_t > v_indices
 
std::unordered_map< const Halfedge *, size_t > h_indices
 
GL::LineSet halfedge_arrows
 
std::shared_ptr< spdlog::logger > logger
 

静态 Private 属性

static std::size_t next_available_id = 0
 

友元

bool operator< (const EdgeRecord &a, const EdgeRecord &b)
 

详细描述

半边网格整体。

当 Dandelion 进入建模模式时,Scene 对象将用选中的 mesh 构造一个半边网格, 从而支持各种基于半边网格的几何算法。当几何操作完成后,需要将半边网格的几何信息 (坐标、连接关系等)同步到原先的 mesh,这样才能显示操作带来的变化。

各种全局操作往往需要频繁增删几何元素,为了保证 \(O(1)\) 的增删效率, 所有的几何元素都存储于双向链表 (LinkedList) 中。

构造及析构函数说明

◆ HalfedgeMesh() [1/2]

HalfedgeMesh::HalfedgeMesh ( Object & object)

指定一个 GL::Mesh 作为参照,构造半边网格。

◆ HalfedgeMesh() [2/2]

HalfedgeMesh::HalfedgeMesh ( HalfedgeMesh & other)
delete

全局只有一个半边网格实例,因此不允许复制构造。

◆ ~HalfedgeMesh()

HalfedgeMesh::~HalfedgeMesh ( )

析构时会调用 clear_erasure_records 释放所有已删除元素占据的内存。

成员函数说明

◆ clear_erasure_records()

void HalfedgeMesh::clear_erasure_records ( )
private

释放内存并清除已删除元素的记录。

这个函数执行 delete 释放内存,并清空各 erased_[elements] 容器中存储的删除记录。

◆ collapse_edge()

optional< Vertex * > HalfedgeMesh::collapse_edge ( Edge * e)

坍缩一条边。

将传入的边坍缩成一个顶点,原先连接到两个端点上的其他边全部连接到这个顶点; 如果这条边的某个邻接面是三角形面,这个邻接面会被坍缩成一条边。

不加检查地坍缩一条边有可能破坏 mesh 的流形性质。假设边端点分别为 \(v_1,v_2\), 此函数仅当

\[ \mathcal{N}_1(v_1)\cap\mathcal{N}_1(v_2) = 2 \]

时才执行坍缩,以免破坏流行性质。

返回
如果坍缩成功,返回坍缩后的顶点;反之返回 std::nullopt

◆ erase() [1/4]

void HalfedgeMesh::erase ( Edge * e)
private

删除一条边。

◆ erase() [2/4]

void HalfedgeMesh::erase ( Face * f)
private

删除一个面。

◆ erase() [3/4]

void HalfedgeMesh::erase ( Halfedge * h)
private

删除一条半边。

◆ erase() [4/4]

void HalfedgeMesh::erase ( Vertex * v)
private

删除一个顶点。

◆ flip_edge()

optional< Edge * > HalfedgeMesh::flip_edge ( Edge * e)

翻转一条边。

由于翻转边的过程中所有几何基本元素数量不变,可以在不增删元素的前提下实现这个函数。 在此情况下,返回的就是被传入的边。如果实现过程中删除了原有的边, 返回的指针可能与传入的不同。

但无论采用哪种实现方法,都不应该翻转 mesh 边界上的边。

返回
如果翻转成功,返回被翻转的边;反之返回 std::nullopt

◆ halfedge_arrow_endpoints()

tuple< Vector3f, Vector3f > HalfedgeMesh::halfedge_arrow_endpoints ( const Halfedge * h)
static

返回绘制半边时的起点和终点坐标。

◆ isotropic_remesh()

void HalfedgeMesh::isotropic_remesh ( )

执行一次重网格化。

该函数采用各向同性重网格化策略调整 mesh 的边,尽可能让每个顶点的度都接近 6、 每个面片都接近正三角形。调整时它重复以下过程:

  1. 分裂过长的边
  2. 坍缩过短的边
  3. 通过翻转边让顶点的度数更平均
  4. 将顶点位置向它的 \(\mathcal{N}_1\) 邻域平均值移动

各向同性重网格化只能应用于三角形网格。

◆ loop_subdivide()

void HalfedgeMesh::loop_subdivide ( )

执行一次 Loop 曲面细分。

该函数使用 flip_edgesplit_edge 完成一次 Loop 曲面细分。注意,Loop 曲面细分只能细分三角网格。细分过程使用 is_boundaryon_boundary 等 API 来判断 mesh 边界并进行处理。

◆ new_edge()

Edge * HalfedgeMesh::new_edge ( )
private

创建一条边。

◆ new_face()

Face * HalfedgeMesh::new_face ( bool is_boundary = false)
private

创建一个面片,可以是真实存在的面片也可以是代表边界的虚拟面片。

◆ new_halfedge()

Halfedge * HalfedgeMesh::new_halfedge ( )
private

创建一条半边。

◆ new_vertex()

Vertex * HalfedgeMesh::new_vertex ( )
private

创建一个顶点。

◆ regenerate_halfedge_arrows()

void HalfedgeMesh::regenerate_halfedge_arrows ( )
private

重新生成所有半边对应的箭头,在更新绘制数据时使用。

◆ render()

void HalfedgeMesh::render ( const Shader & shader)

渲染所有的半边(不负责渲染顶点、边和面片)。

◆ simplify()

void HalfedgeMesh::simplify ( )

执行一次曲面简化。

该函数根据二次误差度量 (Quadric Error Metric, QEM) 确定损失最小的边, 再用 collapse_edge 坍缩它从而减少面数,直至面数减为简化前的 1/4 或找不到可以坍缩的边为止。

◆ split_edge()

optional< Vertex * > HalfedgeMesh::split_edge ( Edge * e)

分裂一条边。

将传入的边分裂成两条边,分裂处新增一个顶点,并将此顶点与相对位置的两个顶点连接。 分裂操作要求指定边的两个邻接面都是三角形面。

返回
如果分裂成功,返回新增顶点;反之返回 std::nullopt

◆ sync()

void HalfedgeMesh::sync ( )

将当前半边网格的几何结构同步到数据源 mesh。

◆ validate()

optional< HalfedgeMeshFailure > HalfedgeMesh::validate ( )
private

检查半边网格的状态。

这个函数可以检查半边网格中的连接关系是否正确、指针是否悬垂,有助于及时发现错误。 错误信息会被输出到日志,并返回一个错误枚举值(参考 HalfedgeMeshFailure 类的说明)。

返回
如果发现错误,返回相应的错误枚举值;反之为 std::nullopt

友元及相关符号说明

◆ operator<

bool operator< ( const EdgeRecord & a,
const EdgeRecord & b )
friend

排序 EdgeRecord 所需的比较运算符重载。

类成员变量说明

◆ edges

LinkedList<Edge> HalfedgeMesh::edges

所有边。

◆ erased_edges

std::unordered_map<size_t, Edge*> HalfedgeMesh::erased_edges
private

已删除的边。

◆ erased_faces

std::unordered_map<size_t, Face*> HalfedgeMesh::erased_faces
private

已删除的面。

◆ erased_halfedges

std::unordered_map<size_t, Halfedge*> HalfedgeMesh::erased_halfedges
private

已删除的半边。

◆ erased_vertices

std::unordered_map<size_t, Vertex*> HalfedgeMesh::erased_vertices
private

已删除的顶点。

◆ error_info

std::optional<HalfedgeMeshFailure> HalfedgeMesh::error_info

在创建半边网格时设置,如果创建正常则为 std::nullopt

◆ faces

LinkedList<Face> HalfedgeMesh::faces

所有面片。

◆ global_inconsistent

bool HalfedgeMesh::global_inconsistent

全局一致性。成功完成一次全局操作后,此变量将置为真,表示需要同步到参照 mesh。

◆ h_indices

std::unordered_map<const Halfedge*, size_t> HalfedgeMesh::h_indices
private

将半边网格的半边指针映射为 GL::LineSet 中的箭头索引。

◆ halfedge_arrows

GL::LineSet HalfedgeMesh::halfedge_arrows
private

用于渲染半边的 LineSet 对象。

◆ halfedges

LinkedList<Halfedge> HalfedgeMesh::halfedges

所有半边。

◆ inconsistent_element

std::variant<std::monostate, Vertex*, Edge*, Face*> HalfedgeMesh::inconsistent_element

当前处于不一致状态的几何基本元素。

在 GUI 上选中了半边网格中的某个元素后,控制器将设置该属性,sync 函数根据该属性的值在每一帧更新数据源 mesh 中的顶点坐标,让建模模式下可以实时预览形变效果。

◆ logger

std::shared_ptr<spdlog::logger> HalfedgeMesh::logger
private

日志记录器。

◆ mesh

GL::Mesh& HalfedgeMesh::mesh
private

数据源 mesh,用于构造半边网格,需要同步修改。

◆ next_available_id

size_t HalfedgeMesh::next_available_id = 0
staticprivate

用于构造半边网格几何元素时分配新的唯一 ID。

◆ object

Object& HalfedgeMesh::object
private

数据源 mesh 对应的物体。

◆ v_indices

std::unordered_map<const Vertex*, size_t> HalfedgeMesh::v_indices
private

将半边网格中的顶点指针映射为 GL::Mesh 使用的顶点索引。

◆ v_pointers

std::vector<Vertex*> HalfedgeMesh::v_pointers

GL::Mesh 使用的顶点索引映射为半边网格中的顶点指针。

◆ vertices

LinkedList<Vertex> HalfedgeMesh::vertices

所有顶点。


该类的文档由以下文件生成: