Browse Source

fix: 'insert_polyline_corner_fillets' ZX coordinate mapping problem

main
linchforever 2 days ago
parent
commit
557f1e49d9
  1. 3
      primitive_process/interface/subface/geometry/polyline_fillet.hpp
  2. 1
      primitive_process/src/subface/geometry/extrude_helixline_geometry.cpp
  3. 48
      primitive_process/src/subface/geometry/extrude_polyline_geometry.cpp
  4. 4
      primitive_process/src/subface/geometry/polyline_fillet.cpp

3
primitive_process/interface/subface/geometry/polyline_fillet.hpp

@ -9,9 +9,6 @@ struct fillet_config_t {
double segment_ratio = 0.05 ;// 圆角切除量占相邻两段中较短段弦长的比例
double min_turn_angle_deg = 0.5; // 低于此角度(度)的衔接处视为共线,跳过
// 最小圆角半径。
double min_fillet_radius = 0.0;
// 当锐角过尖(turn_angle > max_fillet_angle_deg),
// 即使达到 min_fillet_radius 也无法避免自相交时的处理策略:
// true → 跳过该顶点(保留原始尖角,不插入圆弧)

1
primitive_process/src/subface/geometry/extrude_helixline_geometry.cpp

@ -17,7 +17,6 @@ void extrude_helixline_geometry_t::build()
std::vector<double> filleted_bgs;
const fillet_config_t fillet_cfg{/*segment_ratio=*/0.05,
/*min_turn_angle_deg=*/0.5,
/*min_fillet_radius=*/0.0, // profile 自身不需要最小半径约束
/*is_axis=*/true};
insert_polyline_corner_fillets(profile_desc, filleted_pts, filleted_bgs, fillet_cfg);

48
primitive_process/src/subface/geometry/extrude_polyline_geometry.cpp

@ -4,54 +4,16 @@
namespace internal
{
/// 计算 profile 截面的最大半径(原点到各顶点的最大距离)。
/// 用于确保 axis 圆角半径 > profile 半径,防止挤出体内侧自相交。
static double compute_profile_max_radius(const polyline_descriptor_t& profile_desc)
{
if (profile_desc.point_number == 0 || profile_desc.points == nullptr) return 0.0;
double max_r2 = 0.0;
for (uint32_t i = 0; i < profile_desc.point_number; ++i) {
const double x = profile_desc.points[i].x;
const double y = profile_desc.points[i].y;
max_r2 = std::max(max_r2, x * x + y * y);
}
// 如果有 bulge 圆弧,圆弧中点可能更远,粗略扩大 10%
if (profile_desc.bulges != nullptr) {
double arc_extra = 0.0;
for (uint32_t i = 0; i < profile_desc.point_number; ++i) {
const double b = profile_desc.bulges[i];
if (std::abs(b) < 1e-12) continue;
// 圆弧中点偏离弦的距离 = chord/2 * |b|
const uint32_t j = (i + 1) % profile_desc.point_number;
const double dx = profile_desc.points[j].x - profile_desc.points[i].x;
const double dy = profile_desc.points[j].y - profile_desc.points[i].y;
arc_extra = std::max(arc_extra, 0.5 * std::sqrt(dx * dx + dy * dy) * std::abs(b));
}
return std::sqrt(max_r2) + arc_extra;
}
return std::sqrt(max_r2);
}
void extrude_polyline_geometry_t::build()
{
const auto& profile_desc = this->descriptor.profiles[0];
const auto& axis_desc = this->descriptor.axis;
const double profile_max_radius = compute_profile_max_radius(profile_desc);
const double axis_min_fillet_radius = profile_max_radius * 0.01;
std::cout << "[extrude_polyline_geometry_t::build] profile_max_radius=" << profile_max_radius
<< ", axis_min_fillet_radius=" << axis_min_fillet_radius << "\n";
std::vector<vector3d> filleted_axis_pts;
std::vector<double> filleted_axis_bgs;
const fillet_config_t axis_fillet_cfg{
/*segment_ratio=*/0.15,
/*segment_ratio=*/0.01,
/*min_turn_angle_deg=*/0.5,
/*min_fillet_radius=*/axis_min_fillet_radius,
/*is_axis=*/true};
insert_polyline_corner_fillets(axis_desc, filleted_axis_pts, filleted_axis_bgs, axis_fillet_cfg);
@ -68,18 +30,10 @@ void extrude_polyline_geometry_t::build()
axis_geom.build_as_axis(filleted_axis_desc, profile_desc.reference_normal, axis_to_world, polyline_aabb);
for (uint32_t k = 0; k < axis_desc.point_number; ++k) {
polyline_aabb.extend(Eigen::Vector3d(axis_desc.points[k].x, axis_desc.points[k].y, axis_desc.points[k].z));
}
polyline_aabb.min().array() -= profile_max_radius;
polyline_aabb.max().array() += profile_max_radius;
// 对 profile 截面插入圆角(不需要最小半径约束)
std::vector<vector3d> filleted_profile_pts;
std::vector<double> filleted_profile_bgs;
const fillet_config_t profile_fillet_cfg{/*segment_ratio=*/0.05,
/*min_turn_angle_deg=*/0.5,
/*min_fillet_radius=*/0.0, // profile 自身不需要最小半径约束
/*is_axis=*/false};
insert_polyline_corner_fillets(profile_desc, filleted_profile_pts, filleted_profile_bgs, profile_fillet_cfg);

4
primitive_process/src/subface/geometry/polyline_fillet.cpp

@ -121,8 +121,8 @@ void insert_polyline_corner_fillets(const polyline_descriptor_t& desc,
if (cfg.is_axis) {
// axis:XZ 平面
to_2d = [](const vector3d& p) -> Eigen::Vector2d {return {p.x, p.z};};
to_3d = [](const Eigen::Vector2d& q, double fixed_y) -> vector3d { return {q.x(), fixed_y, q.y()};};
to_2d = [](const vector3d& p) -> Eigen::Vector2d { return {p.z, p.x}; }; // 3D -> 2D: (Z, X)
to_3d = [](const Eigen::Vector2d& q, double fixed_y) -> vector3d {return {q.y(), fixed_y, q.x()};}; // 2D -> 3D: (X, Y, Z) = (q.y, fixed_y, q.x)
} else {
// profile:XY 平面
to_2d = [](const vector3d& p) -> Eigen::Vector2d {return {p.x, p.y};};

Loading…
Cancel
Save