#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 #include #include namespace vde::brep { /** * @brief B-Rep 模型的综合验证结果 * * 包含所有检查项的详细报告,用于诊断和修复几何问题。 * * ## 结果解读 * * - `valid == true`: 模型通过所有严格检查,可用于布尔运算和生产用途 * - `valid == false`: 存在一个或多个问题,参见 errors 列表了解详情 * - `warnings` 中的内容不影响 valid 判定,但值得关注(如边过长等) */ struct ValidationResult { /** @brief 是否通过所有必要检查 */ bool valid = true; /** @brief 错误信息列表(导致 valid = false) */ std::vector errors; /** @brief 警告信息列表(不影响 valid) */ std::vector 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::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 对 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