131 lines
5.4 KiB
C++
131 lines
5.4 KiB
C++
|
|
#pragma once
|
|||
|
|
/**
|
|||
|
|
* @file visualization_quality.h
|
|||
|
|
* @brief 网格可视化增强与质量评估
|
|||
|
|
*
|
|||
|
|
* 提供环境光遮蔽、硬边检测/高亮、线框叠加、法线可视化等渲染辅助数据。
|
|||
|
|
* 所有函数输出纯数据(颜色数组、线段数组等),由渲染管线消费。
|
|||
|
|
*
|
|||
|
|
* @ingroup mesh
|
|||
|
|
*/
|
|||
|
|
#include "vde/mesh/halfedge_mesh.h"
|
|||
|
|
#include "vde/core/point.h"
|
|||
|
|
#include <vector>
|
|||
|
|
#include <array>
|
|||
|
|
#include <utility>
|
|||
|
|
#include <cstdint>
|
|||
|
|
|
|||
|
|
namespace vde::mesh {
|
|||
|
|
using core::Point3D;
|
|||
|
|
using core::Vector3D;
|
|||
|
|
|
|||
|
|
// ═══════════════════════════════════════════════════════════
|
|||
|
|
// 数据结构
|
|||
|
|
// ═══════════════════════════════════════════════════════════
|
|||
|
|
|
|||
|
|
/// 逐顶点 AO 值
|
|||
|
|
struct AOResult {
|
|||
|
|
std::vector<double> vertex_ao; ///< 逐顶点环境光遮蔽因子 [0,1](1=完全暴露)
|
|||
|
|
double min_ao; ///< 最小 AO 值
|
|||
|
|
double max_ao; ///< 最大 AO 值
|
|||
|
|
double avg_ao; ///< 平均 AO 值
|
|||
|
|
int samples; ///< 实际采样数
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/// 硬边检测结果
|
|||
|
|
struct EdgeHighlightResult {
|
|||
|
|
std::vector<std::pair<int,int>> hard_edges; ///< 硬边:(vA, vB) 顶点索引对
|
|||
|
|
std::vector<double> edge_angles; ///< 对应二面角(弧度)
|
|||
|
|
double angle_threshold; ///< 使用的角度阈值
|
|||
|
|
int total_edges; ///< 检测总边数
|
|||
|
|
int hard_count; ///< 硬边数
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/// 线框叠加线段
|
|||
|
|
struct WireframeOverlay {
|
|||
|
|
std::vector<std::pair<int,int>> wire_edges; ///< 线框边:(vA, vB)
|
|||
|
|
std::vector<Point3D> vertices; ///< 顶点坐标
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/// 法线可视化数据
|
|||
|
|
struct NormalVisData {
|
|||
|
|
std::vector<Point3D> face_centers; ///< 面中心
|
|||
|
|
std::vector<Vector3D> face_normals; ///< 面法线
|
|||
|
|
std::vector<Point3D> vertex_positions; ///< 顶点位置
|
|||
|
|
std::vector<Vector3D> vertex_normals; ///< 顶点法线(平均面法线)
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// ═══════════════════════════════════════════════════════════
|
|||
|
|
// 环境光遮蔽
|
|||
|
|
// ═══════════════════════════════════════════════════════════
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 计算逐顶点环境光遮蔽(Ambient Occlusion)
|
|||
|
|
*
|
|||
|
|
* 对每个顶点在其上半球采样 `samples` 条射线,统计被遮挡比例。
|
|||
|
|
* AO = 1 - (被遮挡射线数 / 总射线数)。
|
|||
|
|
*
|
|||
|
|
* @param mesh 三角网格
|
|||
|
|
* @param samples 每顶点采样射线数(默认 128,越多越精确)
|
|||
|
|
* @return AOResult 包含逐顶点 AO 值及统计信息
|
|||
|
|
*
|
|||
|
|
* @ingroup mesh
|
|||
|
|
*/
|
|||
|
|
AOResult ambient_occlusion(const HalfedgeMesh& mesh, int samples = 128);
|
|||
|
|
|
|||
|
|
// ═══════════════════════════════════════════════════════════
|
|||
|
|
// 边高亮(硬边检测)
|
|||
|
|
// ═══════════════════════════════════════════════════════════
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 检测硬边(二面角超过阈值的边)
|
|||
|
|
*
|
|||
|
|
* 遍历网格所有边,计算相邻两面的二面角,
|
|||
|
|
* 角度超过 angle_threshold(弧度)的边标记为硬边。
|
|||
|
|
*
|
|||
|
|
* @param mesh 三角网格
|
|||
|
|
* @param angle_threshold 硬边阈值(弧度),默认 π/4 = 45°
|
|||
|
|
* @return EdgeHighlightResult
|
|||
|
|
*
|
|||
|
|
* @ingroup mesh
|
|||
|
|
*/
|
|||
|
|
EdgeHighlightResult edge_highlighting(const HalfedgeMesh& mesh,
|
|||
|
|
double angle_threshold = 0.785398163);
|
|||
|
|
|
|||
|
|
// ═══════════════════════════════════════════════════════════
|
|||
|
|
// 线框叠加
|
|||
|
|
// ═══════════════════════════════════════════════════════════
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 提取线框叠加数据
|
|||
|
|
*
|
|||
|
|
* 从实体网格提取所有唯一边,生成线框表示。
|
|||
|
|
* 可选地排除与 solid_mesh 重合的边(只显示差异边)。
|
|||
|
|
*
|
|||
|
|
* @param mesh 三角网格
|
|||
|
|
* @param solid_mesh 实体网格(空网格 = 忽略)
|
|||
|
|
* @return WireframeOverlay
|
|||
|
|
*
|
|||
|
|
* @ingroup mesh
|
|||
|
|
*/
|
|||
|
|
WireframeOverlay wireframe_overlay(const HalfedgeMesh& mesh,
|
|||
|
|
const HalfedgeMesh& solid_mesh = HalfedgeMesh());
|
|||
|
|
|
|||
|
|
// ═══════════════════════════════════════════════════════════
|
|||
|
|
// 法线可视化
|
|||
|
|
// ═══════════════════════════════════════════════════════════
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 生成法线可视化数据
|
|||
|
|
*
|
|||
|
|
* 计算每个面的中心点与法线、每个顶点法线(相邻面法线的面积加权平均)。
|
|||
|
|
*
|
|||
|
|
* @param mesh 三角网格
|
|||
|
|
* @return NormalVisData
|
|||
|
|
*
|
|||
|
|
* @ingroup mesh
|
|||
|
|
*/
|
|||
|
|
NormalVisData normal_visualization(const HalfedgeMesh& mesh);
|
|||
|
|
|
|||
|
|
} // namespace vde::mesh
|