Files

96 lines
3.4 KiB
C++
Raw Permalink Normal View History

#pragma once
/**
* @file surface_editing.h
* @brief 曲面编辑 — Match Surface(曲面匹配)
*
* 沿共享边界自动调整 target 曲面的控制点,使其与 reference 曲面达到
* G0(位置)、G1(切平面)、G2(曲率)或 G3(曲率变化率)连续性。
*
* 对标 CATIA / NX 的 Match Surface 功能。
*
* @ingroup curves
*/
#include "vde/curves/nurbs_surface.h"
#include "vde/core/point.h"
#include <vector>
namespace vde::curves {
using core::Point3D;
using core::Vector3D;
// ═══════════════════════════════════════════════════════════
// Match Surface — 曲面匹配
// ═══════════════════════════════════════════════════════════
/// 连续性等级
enum class ContinuityLevel {
G0 = 0, // 位置连续(C0
G1 = 1, // 切平面连续(C1
G2 = 2, // 曲率连续(C2
G3 = 3 // 曲率变化率连续(C3
};
/// 边界索引:0=umin, 1=umax, 2=vmin, 3=vmax
enum class BoundaryEdge {
UMin = 0,
UMax = 1,
VMin = 2,
VMax = 3
};
/// 曲面匹配选项
struct MatchSurfaceOptions {
ContinuityLevel continuity = ContinuityLevel::G1; ///< 目标连续性等级
int rows_to_adjust = 0; ///< 待调整控制点排数(0=自动,G0→1, G1→1, G2→2, G3→3
double tolerance = 1e-6; ///< 收敛容差
int boundary_samples = 20; ///< 边界采样点数
bool preserve_weights = true; ///< 是否保持权重不变
bool align_orientation = true; ///< 是否自动对齐曲面朝向
};
/// 曲面匹配结果
struct MatchSurfaceResult {
NurbsSurface matched_surface; ///< 匹配后的 target 曲面
double max_position_error = 0.0; ///< 最大 G0 位置误差
double max_tangent_error = 0.0; ///< 最大 G1 切平面角度误差(弧度)
double max_curvature_error = 0.0; ///< 最大 G2 曲率偏差
double max_derivative_error = 0.0; ///< 最大 G3 曲率变化率偏差
bool g0_ok = false;
bool g1_ok = false;
bool g2_ok = false;
bool g3_ok = false;
int rows_adjusted = 0; ///< 实际调整的控制点排数
std::vector<Point3D> control_displacements; ///< 所有控制点位移
};
/**
* @brief 曲面匹配
*
* 自动调整 target 曲面边界附近的控制点,使其沿 specified edge 与
* reference 曲面达到指定的连续性(G0/G1/G2/G3)。
*
* 算法:
* - G0: 将 target 边界控制点投影到 reference 边界
* - G1: 调整第1排控制点使切平面匹配
* - G2: 调整第1-2排控制点使曲率匹配
* - G3: 调整第1-3排控制点使曲率变化率匹配(最小二乘优化)
*
* @param target 待匹配曲面(边界控制点将被修改)
* @param reference 参考曲面(保持不变)
* @param edge target 曲面要匹配的边界
* @param options 匹配选项
* @return 匹配结果(含修改后曲面和误差统计)
*
* @note G3 需要修改 3 排控制点;G2 修改 2 排;G1/G0 修改 1 排
* @ingroup curves
*/
[[nodiscard]] MatchSurfaceResult match_surface(
const NurbsSurface& target,
const NurbsSurface& reference,
BoundaryEdge edge,
const MatchSurfaceOptions& options = {});
} // namespace vde::curves