Files
茂之钳 05b62e8238
Build & Test / build-and-test (push) Waiting to run
Build & Test / python-bindings (push) Blocked by required conditions
CI / Build & Test (push) Failing after 48s
CI / Release Build (push) Failing after 40s
feat(v5-M1): TrimmedSurface integration + SSI boolean + topology healing + tolerance system
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
2026-07-26 20:35:24 +08:00

117 lines
4.3 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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