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
117 lines
4.3 KiB
C++
117 lines
4.3 KiB
C++
#pragma once
|
||
/**
|
||
* @file ssi_boolean.h
|
||
* @brief 基于曲面-曲面求交 (SSI) 的 B-Rep 布尔运算
|
||
*
|
||
* 这是 B-Rep 布尔运算的完整 SSI 管线实现,与 brep_boolean.h
|
||
* 中基于平面切割的旧实现并存。SSI 方法使用精确的曲面交线来
|
||
* 分割和分类面,从而获得更高质量的布尔结果。
|
||
*
|
||
* ## SSI 管线 (4 步)
|
||
*
|
||
* 1. **SSI 计算** — 对所有面对并行计算曲面交线
|
||
* 2. **面分割** — 用交线分割面,生成 TrimmedSurface 片段
|
||
* 3. **分类** — 射线投射分类每个面片段为 IN/OUT/ON
|
||
* 4. **缝合** — 缝合保留的面片段,调用 heal_orientation
|
||
*
|
||
* ## 精确谓词
|
||
*
|
||
* 分类阶段集成 GMP 精确谓词 (exact_orient3d, exact_point_in_polyhedron),
|
||
* 使用自适应精度:先 double,不确定时自动升级到 GMP。
|
||
*
|
||
* @ingroup brep
|
||
*/
|
||
#include "vde/brep/brep.h"
|
||
#include <chrono>
|
||
#include <string>
|
||
#include <vector>
|
||
|
||
namespace vde::brep {
|
||
|
||
// ═══════════════════════════════════════════════════════════
|
||
// SSI 布尔运算结果
|
||
// ═══════════════════════════════════════════════════════════
|
||
|
||
/**
|
||
* @brief SSI 布尔运算的诊断结果
|
||
*
|
||
* 包含运算过程中的统计信息和诊断数据。
|
||
*/
|
||
struct SSIBooleanResult {
|
||
BrepModel result; ///< 运算结果模型
|
||
|
||
// ── 诊断信息 ──
|
||
int num_ssi_curves = 0; ///< 计算的曲面交线总数
|
||
int num_fragments = 0; ///< 生成的面片段总数
|
||
int num_classified_in = 0; ///< 分类为 IN 的片段数
|
||
int num_classified_out = 0; ///< 分类为 OUT 的片段数
|
||
int num_classified_on = 0; ///< 分类为 ON 的片段数
|
||
int num_kept = 0; ///< 最终保留的片段数
|
||
int num_exact_upgrades = 0; ///< 升级到 GMP 精确谓词的次数
|
||
double ssi_time_ms = 0.0; ///< SSI 计算耗时 (ms)
|
||
double split_time_ms = 0.0; ///< 面分割耗时 (ms)
|
||
double classify_time_ms = 0.0; ///< 分类耗时 (ms)
|
||
double sew_time_ms = 0.0; ///< 缝合耗时 (ms)
|
||
std::string error_message; ///< 错误信息(空表示成功)
|
||
|
||
/// 总耗时 (ms)
|
||
[[nodiscard]] double total_time_ms() const {
|
||
return ssi_time_ms + split_time_ms + classify_time_ms + sew_time_ms;
|
||
}
|
||
};
|
||
|
||
// ═══════════════════════════════════════════════════════════
|
||
// SSI 布尔运算 API
|
||
// ═══════════════════════════════════════════════════════════
|
||
|
||
/**
|
||
* @brief SSI 布尔并集: A ∪ B
|
||
*
|
||
* 合并两个 B-Rep 实体为一个。完整的 SSI 管线:
|
||
* 1. 并行计算所有面对之间的曲面交线
|
||
* 2. 用交线分割面生成面片段
|
||
* 3. 射线投射 + 精确谓词分类每个面片段
|
||
* 4. 缝合保留的面片段并统一方向
|
||
*
|
||
* @param a 第一个 B-Rep 实体
|
||
* @param b 第二个 B-Rep 实体
|
||
* @return SSIBooleanResult 含结果模型和诊断信息
|
||
*
|
||
* @code{.cpp}
|
||
* auto box = make_box(2, 2, 2);
|
||
* auto sphere = make_sphere(1.5);
|
||
* auto r = ssi_boolean_union(box, sphere);
|
||
* if (r.error_message.empty()) {
|
||
* // r.result 是有效的 B-Rep 模型
|
||
* }
|
||
* @endcode
|
||
*/
|
||
[[nodiscard]] SSIBooleanResult ssi_boolean_union(
|
||
const BrepModel& a, const BrepModel& b);
|
||
|
||
/**
|
||
* @brief SSI 布尔交集: A ∩ B
|
||
*
|
||
* 保留两个实体共有的区域。
|
||
*
|
||
* @param a 第一个 B-Rep 实体
|
||
* @param b 第二个 B-Rep 实体
|
||
* @return SSIBooleanResult 含结果模型和诊断信息
|
||
*/
|
||
[[nodiscard]] SSIBooleanResult ssi_boolean_intersection(
|
||
const BrepModel& a, const BrepModel& b);
|
||
|
||
/**
|
||
* @brief SSI 布尔差集: A \ B
|
||
*
|
||
* 从 A 中减去 B 所占据的区域。
|
||
*
|
||
* @param a 被减实体 A
|
||
* @param b 减去实体 B
|
||
* @return SSIBooleanResult 含结果模型和诊断信息
|
||
*/
|
||
[[nodiscard]] SSIBooleanResult ssi_boolean_difference(
|
||
const BrepModel& a, const BrepModel& b);
|
||
|
||
} // namespace vde::brep
|