diff --git a/primitive_process/interface/primitive_descriptor.h b/primitive_process/interface/primitive_descriptor.h index 24bdd3c..54a9591 100644 --- a/primitive_process/interface/primitive_descriptor.h +++ b/primitive_process/interface/primitive_descriptor.h @@ -25,13 +25,13 @@ typedef enum { // double value; // Use 0 to represent an empty body // } constant_descriptor_t; - // Plane descriptor - typedef struct { +// Plane descriptor +typedef struct { //vector3d point; // The base point of the plane //vector3d normal; // The normal of the plane - vector2d local_aabb_min; - vector2d local_aabb_max; - } plane_descriptor_t; + vector2d local_aabb_min; + vector2d local_aabb_max; +} plane_descriptor_t; // Sphere descriptor typedef struct { @@ -156,10 +156,10 @@ inline constexpr cylinder_descriptor_t unit_cylinder{ /// @brief 单位正方形 profile inline const polyline_descriptor_t unit_square_profile = [] { static const std::vector points = { - //{-0.5, -0.5, 0.0}, - //{0.5, -0.5, 0.0}, - //{0.5, 0.5, 0.0}, - //{-0.5, 0.5, 0.0} + {-0.5, -0.5, 0.0}, + {0.5, -0.5, 0.0}, + {0.5, 0.5, 0.0}, + {-0.5, 0.5, 0.0} //{-1.5, -1.5, 0.0}, //{1.5, -1.5, 0.0}, @@ -170,19 +170,19 @@ inline const polyline_descriptor_t unit_square_profile = [] { //{2.0, -0.430871, 0.902414 }, // 局部坐标: (-1, -1) //{2.0, 0.430871, -0.902414} // 局部坐标: (1, -1) - {0.0, 0.430871, -0.902414}, - {0.0, -0.430871, 0.902414 }, - {2.0, 0.1, -0.6}, - {2.0, 0.430871, -0.902414} + //{0.0, 0.430871, -0.902414}, + //{0.0, -0.430871, 0.902414 }, + //{2.0, 0.1, -0.6}, + //{2.0, 0.430871, -0.902414} //{0.0, 0.430871, -0.902414}, // 局部坐标: (1, 1) //{1.0, -0.430871, 0.902414 }, //{6.0, 0.430871, -0.902414} // 局部坐标: (1, -1) }; - // static const std::vector bulges = {0.4, -0.8, 1.0, -0.5}; + static const std::vector bulges = {0.4, -0.8, 1.0, -0.5}; // static const std::vector bulges = {-0.4, 0.8, 0.0, -0.5}; // polyline ERROR // static const std::vector bulges = {0.0, 0.0, -0.5, 0.0}; // helixline ERROR - static const std::vector bulges = {0.0, 0.0, 1.0, 0.0}; // helixline ERROR + //static const std::vector bulges = {0.0, 0.0, 1.0, 0.0}; // helixline ERROR polyline_descriptor_t desc; desc.point_number = 4; desc.points = const_cast(points.data()); @@ -195,12 +195,12 @@ inline const polyline_descriptor_t unit_square_profile = [] { inline const std::vector unit_axis_points = { {0.0, 0.0, -0.5}, - {0.0, 6.0, 6.0 } + {1.0, 0.0, 1.0 } //{4.0, 0.0, 1.0} //{4.0, 0.0, -1.0} }; -inline const std::vector unit_axis_bulges = {0.0}; +inline const std::vector unit_axis_bulges = {0.0, 0.0}; inline const polyline_descriptor_t unit_polyline_axis = [] { polyline_descriptor_t desc; diff --git a/primitive_process/interface/subface/geometry/polyline_fillet.hpp b/primitive_process/interface/subface/geometry/polyline_fillet.hpp index 3fd2c99..272fe19 100644 --- a/primitive_process/interface/subface/geometry/polyline_fillet.hpp +++ b/primitive_process/interface/subface/geometry/polyline_fillet.hpp @@ -6,25 +6,23 @@ namespace internal { struct fillet_config_t { - // 圆角切除量占相邻两段中较短段弦长的比例(默认 5%) - // 越小则圆角越微小,棱角感越强。 - double segment_ratio = 0.05; - // 低于此角度(度)的衔接处视为共线,跳过不处理 - double min_turn_angle_deg = 0.5; + 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 → 跳过该顶点(保留原始尖角,不插入圆弧) + // false → 用最大允许 trim 插入圆弧(会有轻微自相交,但尽力修复) + bool is_axis = false; }; -// 对 2D profile 多段线的衔接顶点插入微小圆角弧,实现 G1 连续。 -// -// 闭合多边形:处理全部 n 个顶点,输出隐式首尾相连。 -// 不闭合多段线:仅处理内部顶点 [1, n-2],首尾端点原样保留。 -// -// @param profile 原始 profile descriptor(通过 is_closed 区分开闭) -// @param out_points 输出点列表 -// @param out_bulges 输出 bulge 列表(与 out_points 等长) -// @param cfg 圆角参数 +// 对 2D profile / axis 多段线的衔接顶点插入微小圆角弧,实现 G1 连续。 void insert_polyline_corner_fillets(const polyline_descriptor_t& profile, - std::vector& out_points, - std::vector& out_bulges, - const fillet_config_t& cfg = {}); + std::vector& out_points, + std::vector& out_bulges, + const fillet_config_t& cfg = {}); } // namespace internal \ No newline at end of file diff --git a/primitive_process/src/subface/geometry/geometry_data.cpp b/primitive_process/src/subface/geometry/geometry_data.cpp index bc1e4d6..c994183 100644 --- a/primitive_process/src/subface/geometry/geometry_data.cpp +++ b/primitive_process/src/subface/geometry/geometry_data.cpp @@ -374,9 +374,6 @@ void polyline_geometry_data::build_as_axis(polyline_descriptor_t&& const auto base_vec1 = *iter - *(iter + 1); // 起点 - 圆心 const auto base_vec2 = *(iter + 2) - *(iter + 1); // 切线辅助点 d - 圆心 c Eigen::Vector2d p_vec; - double cross_bv = base_vec1.x() * base_vec2.y() - base_vec1.y() * base_vec2.x(); - bool is_cw = (cross_bv < 0); - if (this->is_axis) { p_vec = Eigen::Vector2d(p[2], p[0]) - *(iter + 1); } else { @@ -397,22 +394,12 @@ void polyline_geometry_data::build_as_axis(polyline_descriptor_t&& const auto local_x = base_vec1.dot(p_vec); const auto local_y = base_vec2.dot(p_vec); double phi = std::atan2(local_y, local_x); - - // 根据圆弧转向调整 phi - if (!is_cw) { - // CCW: 有效区间 [0, theta] - if (theta > pi + 1e-9) { - if (phi < -EPSILON) phi += two_pi; - } else { - if (phi < -EPSILON) phi = -1.0; // 触发端点回退 - } + if (theta > pi + 1e-9) { + if (phi < -EPSILON) { phi += two_pi; } } else { - // CW: 有效区间 [-theta, 0],翻转后统一用 [0, theta] 处理 - phi = -phi; // 将 CW 的 phi 反号,使有效范围变为 [0, theta] - if (theta > pi + 1e-9) { - if (phi < -EPSILON) phi += two_pi; - } else { - if (phi < -EPSILON) phi = -1.0; + // 劣弧:phi 只应在 [0, theta],负值直接视为 gap + if (phi < -EPSILON) { + phi = -1.0; // 强制触发端点回退 } } @@ -438,7 +425,7 @@ void polyline_geometry_data::build_as_axis(polyline_descriptor_t&& std::sqrt(off_plane * off_plane + dis_on_plane * dis_on_plane), 1., true - }; + }; }; // 计算每个线段的最近点 @@ -452,10 +439,10 @@ void polyline_geometry_data::build_as_axis(polyline_descriptor_t&& // 全局最小值:segment 内局部 t ∈ [0,1],加上段索引得到全局 t const auto iter = std::min_element(closest_params.begin(), closest_params.end()); iter->t += static_cast(std::distance(closest_params.begin(), iter)); - return { + return { line_closest_param_t{std::move(iter->point), iter->t, iter->is_peak_value}, iter->dist * iter->dist_sign - }; + }; } [[nodiscard]] bool polyline_geometry_data::pmc(const Eigen::Ref& p, @@ -703,30 +690,6 @@ Eigen::Vector3d helixline_geometry_data::calculate_normal(double t) const // return {f0 / (f0 - f1), true, true}; return {t0 + (t1 - t0) * f0 / (f0 - f1), true, true}; }); - - // [JUMP_DEBUG] 检测是否存在近似等距的第二候选点 - const double best_sq = sq_dist_at(peak_value_param.t); - double second_sq = std::numeric_limits::max(); - double second_t = -1.0; - - for (int64_t k_ = static_cast(rounded_times_start); k_ <= static_cast(rounded_times_end); ++k_) { - const double t_cand = (theta_p + pi / 2.0 + k_ * pi) * inv_line_theta; - if (t_cand < 0.0 || t_cand > 1.0) continue; - const double sq = sq_dist_at(t_cand); - if (sq > best_sq + 1e-14 && sq < second_sq) { - second_sq = sq; - second_t = t_cand; - } - } - - const double gap = std::sqrt(second_sq) - std::sqrt(best_sq); - if (gap < 0.05 && std::sqrt(best_sq) < this->radius * 2.0) { // 仅关注近表面 - static std::atomic cnt{0}; - if (++cnt <= 100) { - std::cout << "[JUMP_WARN] #" << cnt << " best_t=" << peak_value_param.t << " dist=" << std::sqrt(best_sq) - << " | second_t=" << second_t << " dist=" << std::sqrt(second_sq) << " gap=" << gap << "\n"; - } - } } // if we need to refine the guess, just do it!!!