05b62e8238
M1.1 — TrimmedSurface 深度集成 (Agent #0): - trimmed_surface.h: winding number, closest_boundary_point, to_mesh() with CDT - factory methods: from_rect_with_hole, from_cylinder_patch, from_sphere_patch - brep.h: TopoFace +trimmed_surface_id, add_trimmed_surface() - brep.cpp: to_mesh() prefers TrimmedSurface path - modeling.cpp: make_box uses TrimmedSurface, added make_sphere_patch() - 23 tests, compilation passes M1.2 — SSI 基布尔运算 (Agent #1): - ssi_boolean.h/.cpp: full SSI pipeline (Step1-4) - Step1: parallel face-face SSI, Step2: face splitting via TrimmedSurface - Step3: ray-cast classification + exact predicates, Step4: face sewing - GMP exact predicates integrated (16 references to exact_orient3d/in_sphere) - OpenMP parallel (4 #pragma omp sections) - 33 tests, syntax-check passes M1.3 — 拓扑修复 + 容差系统 (Agent #2): - brep_heal.h/.cpp: heal_gaps (BFS), heal_slivers (Newell area), heal_orientation (Euler) - heal_topology: one-shot pipeline, heal_step_import: STEP auto-heal - tolerance.h: PerFaceTolerance, sliver_area, auto_tolerance(), face_tolerance() - brep_validate.cpp: all hardcoded 1e-6/1e-9 → ToleranceConfig - Tests: tolerance 34/34, heal 24/24, validate 16/16 (all passing) - Fixed: face_area_approx Newell formula bug, heal_step_import reporting 19 files, ~3200 lines net new code, 90+ new tests
119 lines
4.0 KiB
C++
119 lines
4.0 KiB
C++
#pragma once
|
||
/**
|
||
* @file brep_validate.h
|
||
* @brief B-Rep 模型综合验证
|
||
*
|
||
* 对 BrepModel 进行完整性、水密性和拓扑一致性检查。
|
||
* 在生产环境中,验证应在布尔运算、文件导入/导出前后执行。
|
||
*
|
||
* ## 验证项
|
||
*
|
||
* | 检查项 | 字段 | 通过标准 |
|
||
* |--------------------------|-------------------------|-------------------|
|
||
* | 水密性 (watertightness) | watertightness | 1.0 (每条边恰好 2 个面) |
|
||
* | 无自交 | self_intersection_free | 1.0 |
|
||
* | 流形性 | non_manifold_edges | 0 |
|
||
* | 无悬挂边 | dangling_edges | 0 |
|
||
* | 方向一致性 | inconsistent_orientations | 0 |
|
||
* | 边的尺寸 | min/max_edge_length | min > 容差 |
|
||
*
|
||
* @ingroup brep
|
||
*/
|
||
#include "vde/brep/brep.h"
|
||
#include <vector>
|
||
#include <string>
|
||
#include <limits>
|
||
|
||
namespace vde::brep {
|
||
|
||
/**
|
||
* @brief B-Rep 模型的综合验证结果
|
||
*
|
||
* 包含所有检查项的详细报告,用于诊断和修复几何问题。
|
||
*
|
||
* ## 结果解读
|
||
*
|
||
* - `valid == true`: 模型通过所有严格检查,可用于布尔运算和生产用途
|
||
* - `valid == false`: 存在一个或多个问题,参见 errors 列表了解详情
|
||
* - `warnings` 中的内容不影响 valid 判定,但值得关注(如边过长等)
|
||
*/
|
||
struct ValidationResult {
|
||
/** @brief 是否通过所有必要检查 */
|
||
bool valid = true;
|
||
|
||
/** @brief 错误信息列表(导致 valid = false) */
|
||
std::vector<std::string> errors;
|
||
|
||
/** @brief 警告信息列表(不影响 valid) */
|
||
std::vector<std::string> warnings;
|
||
|
||
/** @brief 水密性比率:恰好有 2 个相邻面的边的比例(1.0 = 完美水密) */
|
||
double watertightness = 1.0;
|
||
|
||
/** @brief 无自交比率:不与其他面内部相交的面对比例(1.0 = 无自交) */
|
||
double self_intersection_free = 1.0;
|
||
|
||
/** @brief 最短边的长度(用于检测退化边) */
|
||
double min_edge_length = std::numeric_limits<double>::max();
|
||
|
||
/** @brief 最长边的长度(用于检测超长边) */
|
||
double max_edge_length = 0.0;
|
||
|
||
/** @brief 非流形边数(相邻面 ≠ 2 的边) */
|
||
size_t non_manifold_edges = 0;
|
||
|
||
/** @brief 悬挂边数(无相邻面的边) */
|
||
size_t dangling_edges = 0;
|
||
|
||
/** @brief 方向不一致的面数 */
|
||
size_t inconsistent_orientations = 0;
|
||
|
||
/** @brief 总边数 */
|
||
size_t total_edges = 0;
|
||
|
||
/** @brief 总面数 */
|
||
size_t total_faces = 0;
|
||
|
||
/** @brief 所用容差级别(供外部审查) */
|
||
double tolerance_used = 0.0;
|
||
|
||
/** @brief 欧拉示性数 V - E + F */
|
||
int euler_characteristic = 0;
|
||
};
|
||
|
||
/**
|
||
* @brief 对 BrepModel 执行综合验证
|
||
*
|
||
* 检查以下项:
|
||
*
|
||
* 1. **基本完整性**: 顶点/边/面计数 > 0,ID 引用有效
|
||
* 2. **水密性**: 每条边恰好有 2 个相邻面,构成封闭流形
|
||
* 3. **方向一致性**: 相邻面的法向量方向一致(没有翻转的面)
|
||
* 4. **自交检测**: 面片内部不相交(共享边除外)
|
||
* 5. **边尺寸**: 无退化边(太短)或异常长边
|
||
* 6. **壳闭合性**: 每个标记为 closed 的壳在几何上确实封闭
|
||
*
|
||
* @param body 待验证的 B-Rep 模型
|
||
* @return ValidationResult 包含所有检查结果的详细报告
|
||
*
|
||
* @note 自交检测是最昂贵的检查项(O(n²) 面对数),
|
||
* 对于大模型(> 1000 面)可能需要较长时间。
|
||
*
|
||
* @code{.cpp}
|
||
* auto result = validate(my_model);
|
||
* if (!result.valid) {
|
||
* for (auto& err : result.errors) {
|
||
* std::cerr << "Error: " << err << std::endl;
|
||
* }
|
||
* }
|
||
* if (result.watertightness < 0.99) {
|
||
* std::cerr << "Model is not watertight!" << std::endl;
|
||
* }
|
||
* @endcode
|
||
*
|
||
* @see BrepModel::is_valid() 快速有效性检查(无详细报告)
|
||
*/
|
||
[[nodiscard]] ValidationResult validate(const BrepModel& body);
|
||
|
||
} // namespace vde::brep
|