Files
ViewDesignEngine/include/vde/brep/tolerance.h
T
茂之钳 fcf25e561d feat(v4.4): complete remaining v4.1-v4.4 features + precision tolerance + Euler ops
v4.1 收尾:
- IncrementalUpdateEngine: dirty flag propagation, cache invalidation
- LargeAssembly: InstanceCache, assembly instancing
- STEP import: robust/graceful parsing with skip tracking

v4.3 分析工具:
- Mass properties (volume, centroid, inertia tensor)
- Clearance analysis, wall thickness analysis
- Enhanced drawing: hidden-line removal, offset sections, BOM
- DXF import (LINE/CIRCLE/ARC/LWPOLYLINE/SPLINE → B-Rep extrusion)

v4.4 地基加固:
- ToleranceChain: RSS cumulative tolerance propagation (7 tests)
- Euler operations: MEV/KEV/MEF/KEF/KEMR/MEKR (20 tests)
- Replace hardcoded tolerances with ToleranceConfig in validate
- Fix incremental_update test API mismatch (15/15 pass on Linux)

Docs:
- v4.1-v4.4 development plans + roadmap updated
- v4.4 marked complete on Linux

30 files, +3424/-210
2026-07-26 16:49:37 +08:00

219 lines
7.2 KiB
C++

#pragma once
/**
* @file tolerance.h
* @brief 精确容差系统
*
* 可配置的几何容差,支持 fuzzy 比较和自适应容差。
* 对齐工业 CAD 内核(Parasolid/ACIS)的容差模型。
*
* @ingroup foundation
*/
#include "vde/core/point.h"
#include "vde/brep/brep.h"
#include <cmath>
#include <functional>
#include <string>
#include <vector>
#include <utility>
namespace vde::brep {
// ═══════════════════════════════════════════════════════════
// Tolerance configuration
// ═══════════════════════════════════════════════════════════
/**
* @brief 容差配置
*
* 集中管理所有几何比较的容差值。
* 可全局配置或按操作类型分别设置。
*/
struct ToleranceConfig {
double vertex_merge = 1e-6; ///< 顶点合并容差
double edge_merge = 1e-6; ///< 边合并容差
double face_plane = 1e-9; ///< 面平面判断容差
double boolean = 1e-6; ///< 布尔运算容差
double intersection = 1e-6; ///< 求交容差
double validation = 1e-6; ///< 验证容差
double point_on_curve = 1e-8; ///< 点在曲线上的容差
double point_on_surface = 1e-8; ///< 点在曲面上的容差
double angular = 1e-10; ///< 角度容差(弧度)
/// 全局默认
[[nodiscard]] static const ToleranceConfig& global();
/// 设置全局配置
static void set_global(const ToleranceConfig& cfg);
};
// ═══════════════════════════════════════════════════════════
// Fuzzy comparison utilities
// ═══════════════════════════════════════════════════════════
/**
* @brief Fuzzy 相等(带相对容差)
*
* 使用绝对 + 相对容差组合:
* |a - b| <= max(abs_tol, rel_tol * max(|a|, |b|))
*/
[[nodiscard]] inline bool fuzzy_equal(
double a, double b,
double abs_tol = 1e-9, double rel_tol = 1e-12)
{
double diff = std::abs(a - b);
if (diff <= abs_tol) return true;
double scale = std::max(std::abs(a), std::abs(b));
return diff <= rel_tol * scale;
}
/// Fuzzy 零检查
[[nodiscard]] inline bool fuzzy_zero(double x, double tol = 1e-9) {
return std::abs(x) <= tol;
}
/// Fuzzy 大于
[[nodiscard]] inline bool fuzzy_gt(double a, double b, double tol = 1e-9) {
return a > b + tol;
}
/// Fuzzy 小于
[[nodiscard]] inline bool fuzzy_lt(double a, double b, double tol = 1e-9) {
return a < b - tol;
}
/// Fuzzy 大于等于
[[nodiscard]] inline bool fuzzy_gte(double a, double b, double tol = 1e-9) {
return a >= b - tol;
}
/// Fuzzy 小于等于
[[nodiscard]] inline bool fuzzy_lte(double a, double b, double tol = 1e-9) {
return a <= b + tol;
}
// ═══════════════════════════════════════════════════════════
// Vector fuzzy operations
// ═══════════════════════════════════════════════════════════
/// 两向量在容差内相等
[[nodiscard]] inline bool fuzzy_equal_vec(
const core::Vector3D& a, const core::Vector3D& b, double tol = 1e-9)
{
return fuzzy_equal(a.x(), b.x(), tol) &&
fuzzy_equal(a.y(), b.y(), tol) &&
fuzzy_equal(a.z(), b.z(), tol);
}
/// 两点在容差内相等
[[nodiscard]] inline bool fuzzy_equal_point(
const core::Point3D& a, const core::Point3D& b, double tol = 1e-9)
{
return (a - b).norm() <= tol;
}
/// 两向量平行(共线)
[[nodiscard]] inline bool fuzzy_parallel(
const core::Vector3D& a, const core::Vector3D& b, double angle_tol = 1e-10)
{
double dot = std::abs(a.normalized().dot(b.normalized()));
return fuzzy_equal(dot, 1.0, 1e-9);
}
/// 两向量垂直
[[nodiscard]] inline bool fuzzy_perpendicular(
const core::Vector3D& a, const core::Vector3D& b, double angle_tol = 1e-10)
{
double dot = std::abs(a.normalized().dot(b.normalized()));
return fuzzy_equal(dot, 0.0, angle_tol);
}
// ═══════════════════════════════════════════════════════════
// Adaptive tolerance
// ═══════════════════════════════════════════════════════════
/**
* @brief 根据模型尺寸计算自适应容差
*
* 大模型用宽松容差,小模型用精密容差。
*
* @param model_size 模型特征尺寸
* @param base_tol 基础容差
* @return 自适应容差
*/
[[nodiscard]] inline double adaptive_tolerance(
double model_size, double base_tol = 1e-6)
{
// 1mm 模型 → 0.1μm, 1m 模型 → 100μm
return std::max(base_tol, model_size * 1e-7);
}
/**
* @brief 根据 B-Rep 模型计算容差
*/
[[nodiscard]] double model_tolerance(const BrepModel& body);
// ═══════════════════════════════════════════════════════════
// Tolerance chain — 容差传播追踪
// ═══════════════════════════════════════════════════════════
/**
* @brief 容差传播链
*
* 追踪操作链中的容差累积。每个操作注入自身的容差贡献,
* 末端可查询累积容差上界。
*
* 使用场景:
* - 布尔运算链:求交 → 分割 → 缝合,累积容差逐级放大
* - 特征链:拉伸 → 倒圆 → 抽壳,容差传播路径
*
* @code
* ToleranceChain chain;
* chain.push("intersect", 1e-6);
* chain.push("split", 1e-6);
* chain.push("sew", 1e-5);
* double worst = chain.cumulative(); // 1.2e-5 (root-sum-square)
* @endcode
*/
class ToleranceChain {
public:
/**
* @brief 记录一个操作及其容差贡献
* @param op_name 操作名称(用于调试/日志)
* @param tol 该操作注入的容差
*/
void push(const std::string& op_name, double tol);
/**
* @brief 累积容差
*
* 使用均方根 (RSS) 合成:sqrt(Σ tol²)
* 比简单求和更保守,但比对数叠加更实用。
*
* @return 累积容差
*/
[[nodiscard]] double cumulative() const;
/**
* @brief 最大单步容差
* @return 链中最大的单步容差
*/
[[nodiscard]] double max_step() const;
/** @brief 链深度 */
[[nodiscard]] size_t depth() const { return steps_.size(); }
/** @brief 所有步骤(只读) */
[[nodiscard]] const std::vector<std::pair<std::string, double>>& steps() const {
return steps_;
}
/** @brief 清空链 */
void clear() { steps_.clear(); }
private:
std::vector<std::pair<std::string, double>> steps_;
};
} // namespace vde::brep